profan ² 6.0

Transcription

profan ² 6.0
Roland G. Hülsmann
Hinter der Mühle 6
69226 Nußloch
email: rgh-soft@t-online.de
homepage: http://www.profan.de
Programmieren für Anwender
P R O F A N ² 6.0
DIE einfache Programmiersprache
für Windows 3.x und Windows 95
Einführung
Programmierkurs
Referenz
RGH-PROFAN²
INHALT
Teil 1: Einführung
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Vorbemerkungen
Installation und De-Installation
2.1
Installation
2.2
Was wird benötigt?
2.3
De-Installation
Entwicklungsumgebung
3.1
Übersicht
3.2
Aufruf
3.3
Die Menüpunkte
3.4
Das externe Druckprogramm
PROFAN-SCRIPT
Direktiven für Interpreter und Compiler
5.1
$P+ - Verschlüsselung
5.2
$I - Include-Dateien
5.3
$O - Präprozessor für Operatoren
Operatoren
Variablen - Datentypen - Typumwandlung
7.1
Integer
7.2
LongInt
7.3
Float
7.4
String
7.5
Bereich
7.6
Typumwandlung
7.7
Zahlensysteme
Arrays
8.1
Je Datentyp eine Liste
8.2
Mehrdimensionale Arrays
Kontrollstrukturen
9.1
Case / CaseNot
9.2
If / IfNot - ElseIf - Else - EndIf
9.3
While / WhileNot - EndWhile
9.4
@If
Prozeduren
Funktionen
11.1
Grundlagen
11.2
Allgemeine Funktionen
11.3
Definierte Funktionen
11.4
externe Funktionen
Resourcen
12.1
Allgemeines
12.2
Icons
12.3
Cursor
12.4
Bitmaps
12.5
Strings
12.6
Menüs
12.7
Dialoge
Programm-Aufbau
Befehle über mehrere Zeilen
Fehlerbehandlung - TraceModus
Seite 2
RGH-PROFAN²
16
17
18
19
20
21
22
23
24
25
26
27
28
Text- & Grafikmodus
16.1
Der "Textmodus"
16.2
Der Grafikmodus
Bitmaps
Sounds
Multimediaschnittstelle
19.1
CD-Player
19.2
WAV-Dateien
19.3
MIDI-Dateien
19.4
Video für Windows
Datenbanken
20.1
Grundlagen
20.2
Datenbankstrukturen und Tabellen
20.3
Tabellen bearbeiten
20.4
ODBC-Schnittstelle
Dateien - Verzeichnisse - System - Zwischenablage
21.1
Dateien - Verzeichnisse - System
21.2
Textdateien
21.3
binäre Dateien
21.4
INI-Dateien
21.5
Registry (nur 32 Bit)
21.6
Zwischenablage
21.7
Lange Dateinamen unter Windows 95
Die Verbindung zur Außenwelt
22.1
Drucken mit PROFAN²
22.2
Die serielle Schnittstelle
22.3
I/O-Ports
Vordefinierte Dialoge
23.1
MessageBox
23.2
InputBox und EditBox
23.3
ListBox
23.4
LOAD- und SAVE-Dialoge
Selbstgestaltete Dialoge und Dialogfenster
24.1
Grundlagen
24.2
Buttons - Checkboxen - Radiobuttons
24.3
GroupBoxen - Texte - Icons
24.4
Editierfelder
24.5
ListBoxen
24.6
AuswahlBoxen
24.7
Scrollbalken
24.8
Beliebige Dialogelemente
Kommunikation mit anderen Fenstern - Messages - DDE
25.1
Einfacher Zugriff über das Handle
25.2
Tastatureingaben simulieren
25.3
Messages versenden
25.4
Fernsteuerung per DDE
Menüs und Mäuse
26.1
Fenster-Menüs
26.2
freie PopUp-Menüs
26.3
Warten auf Ereignisse
Spezialitäten für Fortgeschrittene
27.1
Bildschirmschoner
27.2
Neuzeichen selbst übernehmen
27.3
Zeichen in Dialogfenstern
27.4
Messageverwaltung selbst übernehmen
27.5
Zur Verwendung von DLLs
Kompatibilität zu früheren PROFAN-Versionen
Seite 3
RGH-PROFAN²
Teil 2: Programmierkurs
0
1
2
3
4
5
Vorbemerkungen
PROFAN² als Batchsprache
EVA: Eingabe > Verarbeitung > Ausgabe
Grafik und Sound
Multimediaprogrammierung
Selbstdefinierte Dialoge
Teil 3: Referenz
0
1
2
3
4
Übersicht
Systemvariablen
Funktionen
Befehle
Wichtige Messages
ANHANG
1
2
3
Fehlermeldungen
Messages im Überblick
"Technische Daten"
Seite 4
RGH-PROFAN²
Programmieren für Anwender
P R O F A N ² 6.0
DIE einfache Programmiersprache
für Windows 3.x und Windows 95
Teil 1: Einführung
Seite 5
RGH-PROFAN²
1 - VOBEMERKUNGN
PROFAN² ist eine äußerst mächtige Programmiersprache und Batchsprache für Windows
3.1 bzw. Windows 95 in Einem! Außerdem ist PROFAN² auch noch ein SQL-fähiges
Datenbank-Entwicklungssystem mit ODBC-Schnittstelle und direkter dBase-Unterstützung.
Auch die Fähigkeiten als MultiMedia-Entwicklungstool können überzeugen. PROFAN² enthält
beides: Interpreter und schnellen Compiler!
PROFAN² gibt es sowohl als 16-Bit-Version für Windows 3.x als auch als 32-Bit-Version für
Windows 95. Beide Versionen sind zueinander kompatibel, wenn sie sich auch in einigen
"technischen Daten" (siehe Anhang) unterscheiden. Lediglich ein neues Linken mit der 32Bit-Version ist notwendig, um aus einem 16-Bit-Programm ein 32-Bit-Programm zu machen.
Ziele der Entwicklung von PROFAN² waren:
* Eine einfache - an BASIC angelehnte - Syntax auch für den Anfänger
* Traditionelle prozedurale (nicht objektorientierte) Programmmierung
* Alle Grafikmöglichlkeiten, die Windows bietet
* umfangreiche Datei- und Verwaltungsfunktionen
* das komplette Programm in einer nicht zu großen Datei
* keine weiteren DLLs oder sonstige Dateien
* Möglichkeit, Anwendungen ohne weitere Kosten weiterzugeben
Herausgekommen ist bisher "PROFAN² 6.0". Eine komplette Programmiersprache. Der
Anfänger wird viele BASIC-Befehle in gewohnter Form wiederfinden, u.a.
PRINT, LOCATE, CLS, INPUT, IF, WHILE, WEND, SOUND, PRINT #n, INPUT #n, END,
LET, ...
Auch die Variablen und Konstanten werden weitestgehend wie in BASIC gehandhabt, wenn
auch mit dem Bereichs-Typ ein Datentyp eingeführt wurde, der die Flexibilität von Zeigern
bietet, ohne deren Gefährlichkeit in der Anwendung.
Bei den Dateioperationen wurde allerdings das etwas vielseitigere Konzept von PASCAL
übernommen:
ASSIGN, RESET, REWRITE, APPEND, RENAME, ERASE, CLOSE, SETFATTR, ...
Mit COPY können Dateien kopiert werden und mit CHDIR, MKDIR und RMDIR können
Verzeichnisse verwaltet werden. Spezielle Funktionen geben Auskunft über das aktuelle
Laufwerk, den aktuellen Pfad, Attribute, Änderungsdatum und vieles mehr. Unter Windows
95 werden auch in der 16-Bit-Version die langen Dateinamen unterstützt.
Dazu kommen dann noch WINDOWS-spezifische Dinge, wie Menüs, Listboxen, Inputboxen,
Load- und Save-Dialoge, ... um nur ein paar Möglichkeiten zu nennen. Zahlreiche
vorgefertigte Dialogboxen nehmen dem Programmierer bei Standardaufgaben viel Arbeit ab.
Wem das nicht ausreicht, wird mit den vielfältigen Möglichkeiten der Oberflächengestaltung
gedient, die von zwei "Helfern" tatkräftig unterstützt wird. Dialoge können völlig frei gestaltet
und variiert werden. Alle wesentlichen Dialogelemente stehen zur Verfügung.
Sogar der Zugriff auf Resourcen ist möglich, sodaß es z.B. denkbar ist alle Menüs, Dialoge,
Texte, Icons und Bitmaps eines Programmes mit einem Tool wie dem "Resource Workshop"
von Borland in einer DLL oder dem Runtime-Modul unterzubringen
Sehr wichtig sind natürlich die umfangreichen Grafikbefehle, die direkt auf den Grafik-Kern
von Windows zugreifen: USEBRUSH, USEFONT, USEPEN, USEICON, COPYBMP,
RECTANGLE, ROUNDRECT, ELLIPSE, ARC, PIE, DRAWTEXT, ...
Mit LOADBMP und SAVEBMP können Bitmap-Grafiken geladen, verarbeitet und gespeichert
werden. Das Drucken der Grafiken ist natürlich kein Problem!
Seite 6
RGH-PROFAN²
Für den Multimedia-Fan bietet PROFAN² auch einiges: Ansteuerung aller Multimediageräte
und Abspielen von WAV-Sounddateien über die Soundkarte. Über die MIDI-Erweiterung der
Befehle PLAY und MUSIC komponieren Sie mehrstimmige Songs mit den Sounds Ihrer
Soundkarte. Das Abspielen von Musik-CDs ist ebensowenig ein Problem wie das Untermalen
von Spielen mit Geräuschen oder das Abspielen von Microsofts Video für Windows:
MCISEND, PLAYSOUND, ...
PROFAN² hat zahlreiche Datenbankfunktionen zum Lesen und Bearbeiten von DBase IIIkompatiblen Datenbanken. Kleine und mittlere Datenbankanwendungen sind für PROFAN²
kein Problem. Zusätzlich gibt es noch die ODBC-SQL-Schnittstelle hinzu, sodaß PROFAN²
auch im Client-Server-Bereich eine immer größere Rolle spielt. SQL ist auch für PROFAN²
keine Fremdsprache mehr.
Die Kontrolle "fremder" Fenster ist ebenso möglich, wie das Senden von Messages und
Tastaturcodes. Gerade die zahlreichen Windowsbotschaften eröffnen dem Programmierer
umfangreiche Möglichkeiten, auch fremde Anwendungen durch ein PROFAN²-Programm
anzusteuern und zu beeinflussen. Mittels DDE können z.B. Programmanagergruppen
angelegt, umbenannt und auch wieder entfernt werden.
Einige Spezialbefehle und eine Option des Linkers ermöglichen die einfache
Programmierung von ScreenSavern, die über den Windows-Desktop angesteuert werden
können.
Der fortgeschrittene Anwender wird vermutlich zur Bildschirmausgabe die textorientierten
Ausgabebefehle des BASIC weniger verwenden, als vielmehr die neuen und mächtigen
Windows-Befehle, die volle Kontrolle über die Windows-Grafik bieten und auch TrueTypeSchriften voll unterstützen. Text in allen Größen, Farben und Ausrichtungen ist kein
Problem.
Wem all dies nicht ausreicht, der kann Funktionen aus Windows-API und DLLs einbinden
und so den Funktionsumfang nahezu beliebig erweitern.
Strukturierte und übersichtliche Programmierung wird ermöglicht, indem nur ein Befehl pro
Zeile erlaubt ist und zahlreiche Kontrollstrukturen verfügbar sind:
IF ... ELSEIF ... ELSE ... ENDIF, CASE, WHILE ... WEND.
Mit PROC ... ENDPROC können - wie in Pascal - Prozeduren definiert werden und mit DEF
können neue Funktionen definiert werden. In Prozeduren und Funktionen gibt es lokale
Variablen. Außerdem ist beliebiges Einrücken ebenso statthaft, wie komplett leere Zeilen.
PROFAN² hat einen Compiler, der einen sehr kompakten Zwischencode erzeugt, der mit
einem Runtime-Modul gestartet werden kann. Das letzte Glied in der Kette zur kompletten
Programmiersprache ist der Linker, der Runtimemodul und Zwischencode zu einer
eigenständigen EXE- Datei oder zu einem ScreenSaver linkt.
Und da das Runtime-Modul keine 250 kB groß ist, sind recht aufwendige
Windowsapplikationen unter 300 kB möglich. Da die fertige PROFAN-Applikation immer
noch als Runtime-Modul für weitere Zwischencode- Dateien dienen kann und sogar eine
Übergabe von Parametern (über die Zwischenablage) möglich ist, steht der modularisierten
Programmierung nichts im Wege.
Die Sahnehaube aber ist PROFED, die komplette Entwicklungsumgebung, die in der
vorliegenden Version komplett neu programmiert wurde und nun das Editieren nahezu
beliebig großer Dateien zuläßt.
Ach ja: Das berühmte "Hallo Welt"-Programm in Profan:
Print "Hallo Welt"
WaitKey
End
Seite 7
RGH-PROFAN²
So einfach ist das. Das "WaitKey" steht nur deshalb da, damit der Anwender Gelegenheit
hat, das Ergebnis zu betrachten: Ein Programm in einem Windows- Fenster mit allem was
dazugehört. Sozusagen eine vollständige Windows- Applikation. Mit einem Tastendruck oder
über die entsprechende Fensterfunktion wird das Programm beendet.
Die Kombination von Interpreter und Compiler bietet interessante Vorteile. Im
Interpretermodus entwickeln Sie das Programm und testen es aus. Ein zuschaltbarer
TRACE-Modus unterstützt Sie dabei. Und wenn es dann fertig getestet ist, verleihen Sie ihm
mit dem Compiler den nötigen Drive!
... und eine Batchsprache für Windows benötigen Sie auch nicht mehr, wenn Sie PROFAN²
haben!
Seite 8
RGH-PROFAN²
2 - Installation und De-Installation
16-Bit-Version für Windows 3.x:
Ab Version 2.0 ist PROFAN nicht mehr unter Windows 3.0 lauffähig. Mindestens 3.1 muß es
schon sein. Die 16-Bit-Version wurde auch erfolgreich unter Windows 95, Windows NT 3.1
und OS/2 WARP 3.0 getestet. Unter Windows 95 werden ab Version 4.1 auch die langen
Dateinamen unterstützt.
32-Bit-Version für Windows 95:
Diese Version läuft nur unter Windows 95 und - unter Verwendung eines angepaßten
Interpreters und eines angepaßten Runtime-Moduls mit einigen Einschränkungen bei
hardwarenahen Befehlen/Funktionen - Windows NT ab 4.0. Die Einschränkungen sind
jeweils in der Referenz aufgeführt. Unter Windows 3.x mit 32-Bit-Erweiterung Win32s läuft
diese Version nicht.
Die 16-Bit-Version von PROFAN² benötigt mindestens einen 386er mit 4 MB RAM und VGAGrafik. Besser sind - wie für Windows 3.1 allgemein - 8 MB RAM auf einem 386er mit mind.
25 MHz. Windows 3.11 sollte auf einem 486er mit 33 MHz und mind. 8 MB installiert sein
und für Windows 95 sollte es schon ein 486er ab 66 MHz mit 8 oder besser 16 MB RAM
sein. Unterstützt werden SVGA ebenso wie alle nur denkbaren Multimediageräte, die über
die MCI-Schnittstelle angesprochen werden. Die 32-Bit-Version unterstützt wie Windows 95
nicht mehr die Soundausgabe über den PC-Lautsprecher, sodaß eine Soundkarte empfohlen
wird.
2.1 INSTALLATION
PROFAN² ist vom Installationsprogramm auf dem von Ihnen gewählten
gewählten Verzeichnis installiert worden.
Datenträger im
Windows 3.x: Damit PROFAN²-Programme, auch wenn sie nicht zur EXE-Datei gelinkt sind,
durch Doppelklick im Dateimanager (oder was immer Sie an dessen Stelle benutzen)
gestartet werden können, sind folgende Zeilen in die Datei WIN.INI unter dem Abschnitt
"Extensions" einzufügen:
prf=c:\profan\profan.exe ^.prf
prc=c:\profan\profrun.exe ^.prc
(Besitzer der Shareware-Version geben statt "profan.exe" bitte "shprofan.exe" an. Sollten
Sie PROFAN² nicht auf Laufwerk C: in Verzeichnis PROFAN installiert haben, ändern Sie
die Zeilen entsprechend ab.)
Seite 9
RGH-PROFAN²
In Windows 95 werden die entsprechenden Verknüpfungen gemäß der Anleitung von
Windows 95 erstellt. Das 32-Bit-Runtime-Modul heißt PRFRUN32.EXE bzw. für Windows NT
ist es PRFRUNNT.EXE.
Nur die wenigsten Dateien, die das Installationsprogramm auf Ihre Festplatte kopiert hat,
werden wirklich gebraucht. Die meisten Dateien gehören zum Demonstrationsprogramm und
dienen Ihrer Information.
DEMOPROGRAMM - PROGRAMMIERKURS - BEISPIELE - DOKUMENTATION:
Das DEMO-Programm befindet sich
im Unterverzeichnis DEMO, das das
Installationsprogramm unterhalb des PROFAN-Verzeichnisses angelegt hat. Das DEMOProgramm ist komplett in PROFAN² geschrieben. Die Listings sind in der registrierten
Vollversion mit dabei und werden ins Unterverzeichnis BEISPIEL kopiert.
DEMO.EXE - Hauptprogramm
*.PRC - kompilierte Programmodule. Beachten Sie die Kompaktheit selbst so
komplexer Programme, wie RGH-DRAW.
*.PLT - Beispiel-Farbpaletten für Malprogramm und Farbkasten.
*.BMP - Bilder für die Beispielprogramme
*.BLD - Bilder für das Malprogramm
*.WAV - Sounddateien für das Spiel
*.TXT - Texte für den Schnelleinstieg
Im Verzeichnis BEISPIEL:
*.PRF - Listings des DEMO-Programmes
*.INC - Listing der Includedatei zum Malprogramm
Die Dateien zum Programmierkus erkennen Sie an der Endung ".KRS". Sie befinden sich im
PROFAN-Verzeichnis. Die Listungs dazu finden Sie im Unterverzeichnis BEISPIEL.
Im Unterverzeichnis BEISPIEL finden sich außerdem noch weitere Beispielprogramme: CDPlayer, Adressverwaltung, Bidschirmschoner, ...
Die Datei BEISPIEL.WRI listet die
Beispiele samt kurzer Erklärung auf.
Im Unterverzeichnis DOKU befindet sich die wichtige Datei LIESMICH.TXT mit den neuesten
Informationen, sowie Handbücher und weitere informative Dateien im WRITE-Format.
2.2 WAS WIRD BENÖTIGT?
PROFAN² (Entwicklung):
Diese Dateien sind unbedingt notwendig:
(In Klammern steht bei abweichendem
Dateinamen der Name der Datei in der Shareware-Version.)
PROFAN.EXE (SHPROFAN.EXE) - Der Interpreter
PROFED.EXE (SHPROFED.EXE) - Die Entwicklungsumgebung
HELFER.EXE - Runtime für die "Helfer"
*.HLP - Hilfedateien
*.HLF - Die "Helfer"-Programme (Assistenten)
ANSI.EXE - (nur Vollversion) ANSI-Tabelle
PROFCOMP.EXE (SHPRCOMP.EXE) - Der Compiler
PROFLINK.EXE - Der Linker
PROFRUN.EXE - Das Runtime-Modul (16 Bit)
PRFRUN32.EXE - Das Runtime-Modul (Windows 95)
PRFRUNNT.EXE - Das Runtime-Modul (Windows 95 + NT)
PROF16.EXE * (nur 32-Bit-Version)
Seite 10
RGH-PROFAN²
* Wenn Sie aus einem 32-Bit-Programm 16-Bit-DLLs oder Funktionen der 16-Bit-API
aufrufen wollen, benötigen Sie auch PROF16.EXE, welches in Ihrem Windowsverzeichnis
installiert wurde.
Der Hilfegenerator (nicht in der Sharewareversion) benötigt noch folgende Dateien:
HCP.EXE
HCP.ERR
PROFAN² (Anwendung als Batchsprache für Windows):
PROFAN.EXE (SHPROFAN.EXE) - Der Interpreter
*.PRF - Das Batchprogramm (+ Module) in Profan
PROF16.EXE * (nur 32-Bit-Version)
PROFAN² (compilierte Anwendung):
PROFRUN.EXE - Das Runtime-Modul oder ein zur EXE-Datei gelinktes
Profanprogramm
*.PRC - Programm, bzw. Programmmodule
PROF16.EXE * (nur 32-Bit-Version)
Ein zur EXE-Datei gelinktes Profanprogramm ist ohne weitere Dateien eigenständig
lauffähig. Wenn aus 32-Bit-Programmen Zugriffe auf die 16-Bit-API oder 16-Bit-DLLs
erfolgen, wird noch PROF16.EXE im Windowsverzeichnis benötigt.
2.3 DE-INSTALLATION
Wollen Sie PROFAN² von Ihrer Festplatte tilgen - was ich mir kaum vorstellen kann -, so
löschen Sie das einfach das komplette Verzeichnis, in das Sie PROFAN² installiert haben.
Außerdem sind im Windowsverzeichnis noch folgende Dateien installiert worden, die auch zu
löschen sind: TABELLEN.HLP, DIALOGE.HLP, STRUKTUR.HL, FENSTER.HLP und
PROFED16.INI (für die 16-Bit-Version) und PROFED32.INI (32-Bit-Version). Die 32-BitVersion sollte über den entsprechenden Punkt in der Systemsteuerung (Software)
deinstalliert werden.
Seite 11
RGH-PROFAN²
3 - RGH-PROFAN-EDITOR
Der Editor ist eine komplette Entwicklungsumgebung für RGH-PROFAN².
3.1 EDITOR - Übersicht
Multi-File-Editor
Der Editor ist ein "Multi-File"-Editor, das heißt: Es können mehrere Dateien gleichzeitig
editiert werden. Das ermöglicht einfaches Kopieren und Verschieben auch zwischen
verschiedenen Programmen über die Zwischenablage. Um ein anderes Programm oder
einen anderen Text einzusehen, muß das aktuelle Programm nicht verlassen werden. Jedes
Programmfenster kann bis zu 16 MB Text enthalten.
Optionen
Im Optionsmenü findet sich eine Möglichkeit, die Toolbar abzuschalten, man kann endlich
die Tabulatorweite einstellen und es sind alle nichtproportionalen Schriften auswählbar, die
auf Ihrem System installiert sind.
Im Suchen-Menü ist die Möglichkeit hinzugekommen, eine Zeile direkt anzuspringen,
außerdem können die zehn Textmarken angesprungen werden.
Arbeitserleichterung
Im Bearbeiten-Menü gibt es die meisten Erweiterungen: Es können nun nahezu beliebig viele
(8 kB- Puffer) Aktionen rückgängig gemacht werden und dieses Rückgängigmachen kann
auch wieder korrigiert werden. Es können nun komplette Dateien eingefügt werden bzw. kann
auch der markierte Text als Datei gesichert werden. Das Datum und die Zeit können
eingefügt werden und das Wichtigste in dem Menü: Es können bis zu zehn Textmarken
gesetzt werden, die direkt angesprungen werden können. Hierfür gibt es natürlich auch
schnelle Tastencodes, die in der Hilfe nachzuschlagen sind. Gerade bei längeren
Programmtexten entfällt so viel lästiges Blättern.
Rechte Maustaste
Mittels der rechten Maustaste kann im Editoerfenster jederzeit auch ein Kontextmenü
geöffnet werden, das die wichtigsten Bearbeitungsmöglichkeiten bietet.
PROFED16.INI / PROFED32.INI
Außerdem gibt es eine INI-Datei (je nach Version PROFED16.INI bzw. PROFED32.INI), in
der die aktuellen Einstellungen (Schrift, Projektdatei) festgehalten werden. WICHTIG: Um
die aktuellen Einstellungen für den nächten Programmstart zu speichern, muß das
Programm über den Menüpunkt DATEI-ENDE verlassen werden.
Toolbar - Statuszeile
Eine (nun abschaltbare) Toolbar mit den wichtigsten Funktionen vereinfacht die Bedienung
und eine Statuszeile informiert Sie über die aktuelle Kursorposition und ob der Text des
Editors seit dem Laden bzw. letzten Speichern geändert wurde.
Seite 12
RGH-PROFAN²
Helfer und Hilfe
Was in anderen Programmen Wizard oder Assistent genannt wird, ist bei PROFAN² der
Helfer. So gibt es einen Helfer um Datenbanktabellen (Bestandsdateien) zu definieren und
erzeugen, einen Helfer, um Datenbanktabellen zu bearbeiten, einen Helfer um Oberflächen
zu entwerfen und einen Helfer, um Dialogboxen zu gestalten. Zusätzlich gibt es ein
anwenderdefiniertes Menü, in das Sie Ihre meistgebrauchten Werkzeuge und
Hilfsprogramme - etwa den ICON-Editor - aufnehmen können.
Selbstverständlich gibt es eine kontextsensitive Hilfe, die mit <Strg-F1> oder über das
Kontextmenü die Hilfe zum Schlüsselwort anzeigt, auf dem sich der Kursor befindet. (Ein
Markieren des Wortes ist nicht mehr notwendig.)
Projektverwaltung
Eine Projektverwaltung vereinfacht die Arbeit an verschiedenen Projekten. Da man in
verschiedenen Projekten oftmals verschiedene PROFRUN.EXE mit unterschiedlichen Icons
bzw. Resourcen benutzt, kann zu jedem Projekt auch eine eigene PROFRUN.EXE definiert
werden. Voreingestellt ist in der 16-Bit-Version die PROFRUN.EXE und in der 32-Bit-Version
die PRFRUN32.EXE im PROFAN-Verzeichnis, die möglichst nicht verändert werden sollte.
Es ist empfehlenswert, jedem Projekt einen eigenen Pfad zu geben. Ich habe mir angewöhnt,
diesen unterhalb des PROFAN-Verzeichnisses anzulegen. Die Projektdateien speichere ich
im PROFAN-Verzeichnis. Wenn ich nun ein neues Projekt beginne, lege ich mit dem
Dateimanager ein neues Verzeichnis an. Anschließend starte ich PROFAN und erzeuge über
den Menüpunkt "DATEI - NEUES PROJEKT" eine Projektdatei. Im anschließenden
Optionen-Dialog gebe ich Runtime-Modul und Projektverzeichnis an. Anschließend erzeuge
ich mit "DATEI - NEU" eine leere PROFAN-Datei und speichere sie im Projektverzeichnis
ab. Dann speichere ich das Projekt noch einmal ab und nun wird beim Öffnen des Projektes,
immer diese Datei geladen und die anderen Einstellkungen stimmen dann auch.
Drucken
Die Entwicklungsumgebung hat jetzt eine eigene Druckfunktion. Da unter Umständen jedoch
die vielfältigeren Möglichkeiten des externen Druckprogrammes RGH-DRUCK sinnvoll sind,
wird es weiterhin mitinstalliert und kann z.B. in das Benutzermenü der
Entwicklungsumgebung eingebunden werden.
3.2 EDITOR - Aufruf
Sie haben mehrere Möglichkeiten, um mit dem Editor zu arbeiten:
Aufruf mit Kommandozeilenparameter
Sie können beim Aufruf des Editors eine oder mehrere Dateien als
Kommandozeilenparameter angeben. Die Dateien werden beim Start automatisch geladen.
(Der Desktop der letzten Arbeitssitzung mit dem Editor bleibt dabei unberücksichtigt.) Wenn
Sie dem Dateinamen ein @ voranstellen wird dieser als Projektdatei interpretiert. Beispiele:
PROFED beispiel.prf hilfe.txt
PROFED @cdplay.prj
PROFED @cdplay.prj beispiel.prf
Bei der 32-Bit-Version ist statt PROFED das Programm PROFED32 aufzurufen.
Seite 13
RGH-PROFAN²
Aufruf ohne Parameter
Wenn Sie den Editor ohne Parameter (zum Beispiel über das Symbol des ProgrammManagers aufrufen, wird automatisch das Projekt der letzen Arbeitssitzung wiederhergestellt,
das heißt: alle Dateien die damals bearbeitet wurden, werden wieder geladen und in das
entsprechende Verzeichnis gewechselt.
3.3 Die Menüpunkte im Einzelnen:
DATEI - Neues Projekt
Es wird eine neue noch leere Projektdatei unter einem frei zu wählenden Namen gespeichert
(vorgeschlagene Endung .PRJ). Als Projektpfad wird zunächst der Pfad genommen, indem
man sich zur Zeit des Speicherns befindet. Im anschließenden Einstellungsdialog können
jedoch Projekt- und Runtimepfad beliebig eingestellt werden. Alle Dateien, die beim Beenden
oder Speichern des Projektes geöffnet sind, werden dem Projekt hinzugefügt. Wenn man
dann weiterarbeiten will, kann man das Projekt mit allen Dateien laden.
DATEI - Projekt - speichern als
Das aktuelle Projekt (Dateinamen, Runtime-Modul, Projektpfad) wird unter einem frei zu
wählenden Namen gespeichert (vorgeschlagene Endung .PRJ).
DATEI - Projekt laden
Ein gespeichertes Projekt wird mit allen seinen Dateien geöffnet. Bereits vorher geöffnete
Dateien bleiben geöffnet, sodaß man ein Projekt zu einem anderen hinzuladen kann.
DATEI - Projekt schließen
Das aktuelle Projekt wird gespeichert und dann geschlossen: Alle Dateien werden
geschlossen und anschließend das Projekt selbst.
DATEI - Neue Datei
Ein neues RGH-PROFAN-Programm schreiben. Es bekommt zunächst den Namen
"OHNENAME.PRF". Existiert bereits ein Programm "OHNENAME.PRF", so wird es geladen.
Es empfiehlt sich, das Programm sogleich mit "Speichern als" abzuspeichern und ihm einen
neuen Namen zu geben.
DATEI - Datei Öffnen
Eine bereits bestehende Datei wird zum Bearbeiten geöffnet. Die wichtigsten Dateitypen
werden zur Auswahl angeboten.
DATEI - Datei Speichern
Die aktuell aktive PROFAN-Datei wird unter ihrem Namen gespeichert.
Seite 14
RGH-PROFAN²
DATEI - Datei Speichern als
Die aktuell aktive PROFAN-Datei kann unter einem neuen Namen/Pfad abgespeichert
werden.
DATEI - Datei schließen
Die aktuell aktive Datei wird geschlossen. Es wird ggf. nachgefragt, ob Änderungen
gespeichert werden sollen.
DATEI - Drucker einrichten
Der Drucker kann ausgewählt und eingerichtet werden.
DATEI - Drucken
Die aktuelle Datei wird gedruckt. Ist ein Text markiert, kann ausgewählt werden, ob der
gesamte Text oder nur der ausgewählte Teil gedruckt werden soll. Der Programmtext wird
mit Zeilennummern gedruckt.
DATEI - Programm aufrufen
Ein beliebiges EXE-Programm kann über diesen Menüpunkt aufgerufen werden.
DATEI - Ende
Der Editor wird beendet. Sollten Programme nach der Veränderung noch nicht abgespeichert
sein, wird jeweils nachgefragt, ob man dies nun möchte.
BEARBEITEN - Rückgängig
Die letzten Editiervorgänge können noch rückgängig gemacht werden. Der RückgängigPuffer ist so bemessen, daß im Normalfall mehrere hundert bis tausend Editiervorgänge
rückgängig gemacht werden können.
BEARBEITEN - Widerrufen
Die letzten Rückgängig-Aktionen können widerrufen werden.
BEARBEITEN - Ausschneiden
Der markierte Text wird in die Zwischenablage kopiert und aus dem Programm entfernt.
BEARBEITEN - Kopie
Der markierte Text wird in die Zwischenablage kopiert, bleibt aber im Programm.
BEARBEITEN - Einfügen
Der Text der Zwischenablage wird an der Kursorposition eingefügt.
Seite 15
RGH-PROFAN²
BEARBEITEN - Löschen
Der markierte Text wird gelöscht.
BEARBEITEN - Alles auswählen
Der gesamte Text im aktuellen Fenster wird ausgewählt (markiert).
BEARBEITEN - Alles löschen
Der gesamte Text wird gelöscht.
BEARBEITEN - Einfügen aus Datei
Es kann eine Text-Datei ausgewählt werden, deren Inhalt an der Kursorposition eingefügt
wird.
BEARBEITEN - Kopieren als Datei
Der ausgewählte (markierte) Text wird als Datei gespeichert. Es ist der Name der Datei
einzugeben. Existiert die Datei schon, wird sie überschrieben.
BEARBEITEN - Ablage
Die Windows-Zwischenablage wird aufgerufen. So kann man nachsehen, was da gerade drin
ist.
BEARBEITEN - Datum + Zeit
Datum und Zeit werden an der aktuellen Kursorposition eingefügt.
BEARBEITEN - SetzeMerker
An der aktuellen Kursorposition wird eine (sichtbare aber nicht druck- oder speicherbare)
Markierung gesetzt. Es sind die Markierungen 0 bis 9 möglich. Diese Markierungen sind
quasi Lesezeichen, zu denen jederzeit direkt mit <Strg-0> bis <Strg-9> gesprungen werden
kann. Die Markierung kann auch mit <Umsch-Strg-0> bis <Umsch-Strg-9> bzw. über das
Kontextmenü mittels der rechten Maustaste gesetzt werden.
SUCHEN - Finden
Sucht im aktuellen Programmfenster nach einem Text. Es kann angegeben werden, ob
zwischen Groß- und Kleinschreibung zu unterscheiden ist. Mit <Strg-L> kann die Suche
wiederholt werden.
Seite 16
RGH-PROFAN²
SUCHEN - Ersetzen
Sucht im aktuellen Programmfenster nach einem Text und ersetzt ihn durch einen anderen.
Es kann angegeben werden, ob Groß- und Kleinschreibung zu unterscheiden ist, ob im
ganzen Text gesucht werden soll und ob vor jedem Ersetzen nachgefragt werden soll.
SUCHEN - Weitersuchen
Wiederholt die Suche bzw. das Suchen und Ersetzen.
SUCHEN - GeheZuZeile
Es kann direkt eine bestrimmte Zeile angesprungen werden.
SUCHEN - GeheZuMerker
Es wird direkt zur gewählten Markierung gesprungen. Schneller und effektiver läßt sich dies
auch mit Strg-0 bis Strg-9 erreichen. Existiert die Markierung nicht, passiert garnichts.
PROFAN - Ausführen (Interpreter)
Führt ein PROFAN-Programm mit dem Interpreter aus. Das Programm wird von der
Festplatte gelesen. Ist ein noch nicht in der aktuellen Version abgespeichertes Programm im
Editor, wird nachgefragt, ob man es zuvor abspeichern will.
PROFAN - als Script-Datei Ausführen
Führt ein PROFAN-Programm mit PROFAN-SCRIPT aus. Hiermit kann ein Programm auf
seine Tauglichkeit für den Einsatz mit PROFAN-SCRIPT getestet werden. Das Programm
wird von der Festplatte gelesen. Ist ein noch nicht in der aktuellen Version abgespeichertes
Programm im Editor, wird nachgefragt, ob man es zuvor abspeichern will
.
PROFAN - Compilieren
Es wird ein PROFAN-Programm (.PRF) compiliert. Der Compiler PROFCOMP.EXE muß
sich im gleichen Verzeichnis wie der Editor befinden. Das Ergebnis ist eine Datei mit der
Endung .PRC, die vom Runtime-Modul
PROFRUN oder jeder PROFAN-EXE-Datei
ausgeführt werden kann. Die PRC-Datei ist in der Regel nur halb so groß, wie die PRF-Datei,
dafür aber deutlich (!) schneller.
Die entstehende PRC-Datei wird in dem Verzeichnis abgelegt, in dem sich die PRF-Datei
befindet!
PROFAN - Starten
Ein compiliertes PROFAN-Programm wird vom Runtime-Modul gestartet und ausgeführt.
PROFRUN.EXE muß sich im gleichen Verzeichnis wie der Editor oder im
Windowsverzeichnis befinden.
Seite 17
RGH-PROFAN²
PROFAN - EXE-Datei erstellen
Eine PRC-Datei wird mit dem Runtime-Modul zu einer EXE-Datei gelinkt. Der Linker
PROFLINK.EXE muß sich im gleichen Verzeichnis wie der Editor befinden. Die EXE-Datei
kann unter Windows selbstständig ausgeführt werden. Da sie das komplette RUNTIMEModul enthält, kann sie für PRC-Dateien auch als Runtime-Modul dienen.
PROFAN - ScreenSaver erstellen
Eine PRC-Datei wird mit dem Runtime-Modul zu einer SCR-Datei gelinkt. Der Linker
PROFLINK.EXE muß sich im gleichen Verzeichnis wie der Editor befinden. Die SCR-Datei
kann in der Systemsteuerung von Windows als Bildschirmschoner eingebunden werden. Der
Name des Screensavers ist in der 32-Bit-Version der Dateiname; in der 16-Bit-Version wird
er abgefragt.
HELFER - Datenbankstruktur
Mit diesem Modul können Sie Datenbankstrukturen definieren, diese als Templatedateien für
den DBCREATE-Befehl ablegen oder auch die Tabelle gleich erzeugen. Näheres finden Sie
in der Hilfe des Moduls.
HELFER - Tabellen bearbeiten
Mit diesem Modul können Sie beliebige dBase-III kompatiblen Tabellen (*.DBF) bearbeiten.
Mit dem [*] können Sie auf jedes Feld einen Index legen. Der Index wird beim Suchen nach
einem Eintrag mit [Suchen] benutzt. Ohne Index kann in jedem Feld mit [?] gesucht werden.
Hat eine Tabelle mehr als zehn Felder, so können Sie mit [«] und [»] durch die Felder
blättern.
HELFER - Fenster gestalten
Dieser Helfer ermöglicht Ihnen die einfache Gestaltung des Hauptfensters mit den zur
Verfügung stehenden Dialogelementen. Nach dem Aufruf werden Sie gebeten, mit der Maus
die Größe des Fensters zu markieren. Weitere Hilfe entnehmen Sie der Hilfe des Helfers,
indem Sie den Button mit dem Fragezeichen anklicken.
HELFER - Dialoge gestalten
Dieser Helfer ermöglicht die bequeme Gestaltung von Dialogboxen. Zu Beginn können Sie
wählen, ob Sie einen schon erstellten Dialog laden oder mit einem neuen beginnen. In
letzterem Fall müssen Sie zunächst die Größe des Dialogfensters mit der Maus markieren.
Auch dieses Modul hat eine eigene Hilfe.
HELFER - Hilfe erzeugen
Dieser Helfer ermöglicht die einfache Erzeugung einer Windows-Hilfedatei. Damit die
Hildedatei erstellt werden kann, muß der Microsoft-Hilfecompiler HCP.EXE mit HCP.ERR im
PROFAN-Verzeichnis sein. Auch der Hilfegenerator hat eine eigene Hilfe.
Seite 18
RGH-PROFAN²
HELFER - Menü-Designer
Dieser Helfer ermöglicht die rasche und bequeme Gestaltung von Menüs für Ihre PROFAN²Programme. Der Menü-Designer erzeugt den entsprechenden Quellcode als ablauffähiges
Programmgerüst. Nähere Hinweise entnehmen Sie bitte der Hilfe des Menü-Designers.
HELFER - Benutzermenü
Dem Benutzermenü kann ein Eintrag hinzugefügt werden. Es werden zwei Angaben erwartet:
Bezeichnung des Eintrages im Menü und die dazugehörige Befehlszeile. (Um Menüpunkte
zu löschen, muß die Datei PROFED.INI im Windowsverzeichnis bearbeitet werden. Die
Anzahl der Menüpunkte muß angepaßt und die entsprechenden Zeilen gelöscht werden.)
OPTIONEN - Toolbar
Die Toolbar (Icon-Leiste) kann wahlweise ein- oder ausgeschaltet werden.
OPTIONEN - Zeilenumbruch
Der automatische Zeilenumbruch kann wahlweise ein- oder ausgeschaltet werden.
Bei eingeschaltetem Zeilenumbruch werden Wörter, die nicht mehr in die aktuelle
Bildschirmzeile passen, automatisch in die nächste Zeile gesetzt. Diese Einstellung sollte für
die meisten Texte Verwendung finden.
Ohne Zeilenumbruch kann eine Zeile bis zu 32000 Zeichen enthalten. Diese Einstellung ist
zum Bearbeiten von Programmtexten zu empfehlen.
OPTIONEN - Tabulator
Der Tabulator kann eingestellt werden. Defaultmäßig sind 8 Zeichen eingestellt, d.h. [TAB]
bewegt den Kursor auf die 8., 16., 24. etc. Position.
OPTIONEN - Schrift ...
Eine der installierten nichtproportionalen Schriften kann ausgewählt werden.
OPTIONEN - Includepfad
Der Pfad zu den Include-Dateien ist anzugeben. Er kann auch (wie der z.B. DOS-Pfad in der
AUTOEXEC.BAT) mehrere Verzeichnisse durch Semikolon getrennt enthalten. Beispiel:
"C:\PROFAN;C:\PROFAN\INCLUDE". Gesucht wird nach Include-Dateien in folgender
Reihenfolge: 1. Im aktuellen Verzeichnis - 2. Im Includepfad.
OPTIONEN - Projekt-Einstellungen
Hier können Projektpad und Runtime-Modul des Projektes eingestellt werden. Jedem Projekt
kann eine eigene Runtime-Datei (in der Regel PROFRUN.EXE bzw. PRFRUN32.EXE)
zugeordnet werden, die beim Starten und Linken des compilierten Programmes genutzt wird.
Das ist dann besonders sinnvoll, wenn man für ein Projekt eine geänderte PROFRUN.EXE
mit einem eigenen Icon- bzw. Resourcen-Satz verwendet.
Seite 19
RGH-PROFAN²
FENSTER - Nebeneinander / Untereinander
Die verschiedenen Programmfenster im Editor werden nebeneinander, bzw. übereinander
angeordnet, sodaß sie sich nicht überschneiden.
FENSTER - Überlappend
Die Programmfenster werden versetzt hintereinander angeordnet, sodaß von allen die
Titelseite zu sehen ist.
FENSTER - Symbole anordnen
Die Icons der verkleinerten Programmfenster werden in Reih' und Glied gebracht.
FENSTER - Alle schließen
Alle Programmfenster werden geschlossen.
FENSTER - Rechner
Der Windows-Taschenrechner wird für Berechnungen zwischendurch aufgerufen.
FENSTER - Ansi-Tabelle
Eine Ansi-Tabelle wird aufgerufen. Zeichen können aus der Ansi-Tabelle übernommen
werden. (Siehe Hilfetext der ANSI-Tabelle)
FENSTER - Kalender
Der Windows-Kalender wird aufgerufen.
FENSTER - 1 ...
Hier sind alle geöffneten Programme aufgelistet. Wenn man die Editorfenster auf optimale
Größe vergrößert hat, kann durch diese Menüpunkte einfach zwischen den Fenstern
umgeschaltet werden.
? - PROFAN-Hilfe
Die komplette Hilfe zu PROFAN wird aufgerufen. Diese Hilfedatei enthält sowohl die
komplette Einführung als Hypertext, als auch die Referenz mit allen Systemvariablen,
Funktionen und Befehlen
? - Referenz
In der Referenz ist die komplette Programmiersprache RGH-PROFAN² in der aktuellen
Version beschrieben. Im Zweifelsfalle ist diese Referenz aktueller als das entsprechende
Handbuch. Für jede Systemvariable, jede Funktion und jeden Befehl findet sich eine
Syntaxbeschreibung und häufig auch Beispiele.
Seite 20
RGH-PROFAN²
? - kontextabhängige Hilfe
Die Hilfe zum Wort (Befehl/Funktion/Systemvariable), auf dem der Kursor steht, wird
angezeigt. Die kontextabhängige Hilfe kann auch mit <Strg-F1> oder über das Kontextmenü
(rechte Maustaste) aufgerufen werden.
? - Editor
Hilfe zur Entwicklungsumgebung. Alle Menüpunkte werden erläutert.
? - Suche in der Hilfe
Der Such-Dialog der Hilfe wird geöffnet, um nach einem Begriff in der Hilfe zu suchen.
? - Hilfe verwenden
Eine Einführung in die Benutzung der Hilfe-Funktion wird gegeben..
? - Über
Copyright-Vermerk: 1992-1997 - Roland G. Hülsmann, Nußloch.
Seite 21
RGH-PROFAN²
3.4 - RGH-DRUCK
RGH-DRUCK ist ein eigenständiges Programm zum Drucken beliebiger Texte. Es enthält
weitreichende Formatierungsmöglichkeiten.
Die Menüpunkte:
Datei - Öffnen
Datei - Drucken
Datei - Drucker einrichten
Datei - Seitenformat
Datei - Ende
Text - Schrift
Alle diese Funktionen können auch über die entsprechenden Buttons direkt angewählt
werden. Die Bilder sind selbsterklärend.
Im System-Menü von RGH-DRUCK finden sich noch ein weiterer Menüpunkt:
Über ...
Datei - Öffen
Öffnet die zu druckende Datei. Diese wird in den Speicher gelesen und kann auch betrachtet
werden. Änderungen sind jedoch nicht möglich. Lange Texte werden auch nur teilweise
angezeigt, jedoch vollständig gedruckt.
Datei - Drucken
Der Text wird im eingetellten Format mit der eingestellten Schrift gedruckt.
Datei - Drucker einrichten
Sie können den Drucker einrichten: Papierformat wählen, Einzugsschacht festlegen, Drucker
wechseln, etc.
Datei - Seitenformat
Zahlreiche Formatierungen können eingestellt werden: Ränder, Zeilenlineal, Zeilennummern
(bei PROFAN-Listings sinnvoll), ANSI-CC-Byte (in der Regel nicht anzukreuzen), Datum,
Zeit,
Tabulatorgröße. Die Tabulatorgröße sollte der PROFAN-Editors entsprechen;
voreingestellt ist 8. Zusätzlich können Sie noch Kopf- und Fußzeile eingeben.
Datei - Ende
Beendet das Druckprogramm.
Text - Schrift
Es kann eine Schriftart und Schriftgröße gewählt werden. Es ist ratsam eine schmale Schrift
zu verwenden, da Zeilen, die nicht ganz in eine Druckzeile passen, einfach abgeschnitten
werden.
Seite 22
RGH-PROFAN²
Systemsteuerung
Da kann der Drucker (und anderes) eingestellt werden.
Über ...
Copyright-Hinweis. Hinweis auf das amerikanische Programm, dessen Quellcode Grundlage
von RGH-Druck ist: PLXpress 1.3 von Doug Overmyer.
Erweitert und ins Deutsche übertragen von Roland G. Hülsmann.
Seite 23
RGH-PROFAN²
4 - PROFAN-SCRIPT
PROFAN-SCRIPT ist die Internet-Scriptsprache mit einer Untermenge des Befehlsumfanges
der Programmiersprache PROFAN²! Sie binden es in Ihren Web-Browser ein, indem Sie die
Dateiendung 'PSC' mit PROFSCR.EXE verknüpfen. In der Online-Hilfe von PROFAN² bzw.
PROFAN-SCRIPT finden Sie Hinweise zur Verknüpfung mit MS Internet-Explorer, Mosaic
und Netscape.
Ausprobiert werden kann die richtige Einbindung über die PROFAN-SCRIPT-Testseite von
Andreas Schulten u.A. mit einem kleinen Spielchen (5 k, in ca. 2-5 sec geladen):
http://members.aol.com/ASchulten/psc.htm
PROFAN-SCRIPT ist FREEWARE und darf unverändert beliebig weiterverbreitet werden.
Ausdrücklich ist auch die Verbreitung auf CD-ROM und zusammen mit anderen Produkten
erlaubt. Folgende Dateien gehören zu PROFAN-SCRIPT: PROFSCR.EXE (Der Interpreter in
16- oder 32-Bit-Version), PROFSCR.HLP (Hilfedatei) und PSED.EXE (eine minimalistische
Entwicklungsumgebung).
Wenn Sie PROFAN-SCRIPT mit dem PROFAN²-PAKET erhalten haben, wurden die Dateien
für die Weitergabe von PROFAN-SCRIPT (mit Ausnahme des Interpreters) in das
Verzeichnis PRPFSCR unterhalb Ihres PROFAN-Verzeichnisses kopiert. Die entsprechende
PROFSCR.EXE befindet sich im PROFAN²-Verzeichnis.
Mit PROFAN-SCRIPT sind keine Änderungen von Dateien und System des Anwenders
möglich. Es können keine Infos ausgespäht und in das Internet weitergegeben werden!
Seite 24
RGH-PROFAN²
5 - Direktiven für Interpreter und Compiler
Eine Direktive für Interpreter und Compiler beeinflußt die Art, wie der Quelltext interpretiert
bzw. umgesetzt wird. Eine Direktive wird mit einem $ eingeleitet und von einem Buchstaben
gefolgt. Zur Zeit kennt PROFAN² folgende drei Direktiven für Interpreter und Compiler:
5.1 $P+ : Verschlüsselung des Zwischencodes
Wenn diese Direktive im Programm vorkommt, wird der Zwischencode, den der Compiler
erzeugt, verschlüsselt abgespeichert. Texte, die im Programm vorkommen, können dann
nicht mehr mit einem Hex- Editor gelesen werden. So kann keiner Ihre Copyright-Meldungen
oder andere Texte verändern. Dem Runtime-Modul und dem Linker ist es egal, ob der
Zwischencode (die PRC-Datei) verschlüsselt ist oder nicht. Die Ablaufgeschwindigkeit des
Programmes wird nicht beeinflußt, lediglich die Zeit die das Programm vom Aufruf bis zum
Start braucht, wird ein wenig (aber unmerklich) erhöht, da das Programm vor der Ausführung
im Speicher entschlüsselt werden muß.
$P+
Hinweis: Das "P" muß groß geschrieben sein!
5.2 $I : Include-Dateien
Seit PROFAN² 2.0 gibt es auch die Möglichkeiten, Programmodule während des
Compilierens bzw. Interpretierens dazuzuladen. Das geschieht mit der Direktive:
$I <Dateiname>
(Hinter dem großen Buchstaben I muß ein Leerfeld sein.) Für den Interpreter oder Compiler
ist es dann so, als stünde der Inhalt der Datei <Dateiname> an der entsprechenden Stelle im
Programm. Wenn der Dateiname keine Pfadangabe enthält wird die Includedatei zunächst
im aktuellen Verzeichnis und dann im Includepfad gesucht. Der Includepfad wird im EditorMenü "OPTIONEN/Include-Pfad" eingestellt. Beispiel:
Declare Test%, Frage$, Antwort$
$I ZUSATZ.INC
...
Auf diese Weise können häufig gebrauchte Module beliebig oft verwandt werden, ohne daß
sie jedesmal neu eingetippt oder über die Zwischenablage kopiert werden müßten.
Besonders sinnvoll ist diese Methode, wenn man zum Beispiel besonders häufig gebrauchte
Prozeduren oder selbstdefinierte Funktionen in Include-Dateien abspeichert. Ich habe mir
angewöhnt, Includedateien mit der Endung .INC zu versehen.
Seite 25
RGH-PROFAN²
5.3 - $O : Präprozessor für Operatoren
An sich kennt PROFAN² ja keine Operatoren, sondern alles wird in Funktionen ausgedrückt.
Ab Version 4.1 gibt es aber einen integrierten Präprozessor, der in gewissem Maße
Operatoren erlaubt. Dieser Präprozessor übersetzt im Quelltext vorkommende Operatoren in
die übliche PROFAN²-Syntax. Standardmäßig ist dieser Präprozessor ausgeschaltet. Mit
$O+ wird er eingeschaltet und ist so lange aktiv, bis er wieder mit $O- ausgeschaltet wird. Da
der Interpreter bei eingeschaltetem Präprozessor bis zu 50% langsamer wird, sollte man ihn
nur einschalten wenn er benötigt wird. Bei eingeschaltetem Präprozessor benötigt auch der
Compiler etwas länger. Auf die Laufzeit des compilierten Programmes hat der Schalter
keinen Einfluß.
Näheres zu Operatoren siehe im folgenden Kapitel.
Hinweis: Das "O" muß groß geschrieben sein!`
Seite 26
RGH-PROFAN²
6 - Operatoren
Operatoren, wie man sie von anderen Sprachen her kennt, gibt es in PROFAN
normalerweise nicht. Alles wird mittels Funktionen erledigt. Es gibt für alle gewohnten
Operatoren entsprechende Funktionen. Statt
LET A% = A% + 3
muß z.B. geschrieben werden:
LET A% = @ADD(A%,3)
WICHTIG: Das LET darf nicht weggelassen werden.
Diese Philosophie wird auch konsequent bei Vergleichen und Bedingungen eingesetzt:
IF A% = B%
IF A% AND B%
wird zu
wird zu
IF @EQU(A%,B%)
IF @AND(A%,B%)
Ab Version 4.1 besitzt PROFAN² aber einen integrierten Präprozessor, der ansatzweise die
Nutzung von Operatoren ermöglicht. Folgende Operatoren sind zugelassen, wenn der
Präprozessor mit $O+ aktiviert ist:
(A%
(A%
(A%
(A%
(A%
(A%
(A%
(A%
(A%
+
*
/
\
^
<
>
=
B%)
B%)
B%)
B%)
B%)
B%)
B%)
B%)
B%)
entspricht
entspricht
entspricht
entspricht
entspricht
entspricht
entspricht
entspricht
entspricht
@ADD(A%,B%)
@SUB(A%,B%)
@MUL(A%,B%)
@DIV(A%,B%)
@DIV&(A%,B%)
@POW(A%,B%)
@LT(A%,B%)
@GT(A%,B%)
@EQU(A%,B%)
Die zwei (!) mit Operatoren verknüpften Werte müssen in Klammern stehen. (Das ist
besonders bei -, = und > notwendig, da diese Zeichen auch Trennzeichen zwischen
Parametern sein können und vom Präprozessor als solche interpretiert würden.) Ebenso wie
Funktionen können Ausdrücke mit Operatoren verschachtelt werden. Beispiele:
$O+
IF (A% >
LOCATE
ENDIF
LET A% =
SETPIXEL
B%)
(A%+5),(B%-3)
(3 * (B% + C%))
X%,(5*@SIN(Y%)),0
Eine Verknüpfung von mehr als zwei Werten ist ohne zusätzliche Klammerung nicht
möglich!
LET A% = (B% + C% + D%)
ist nicht erlaubt. Statt dessen ist zu schreiben:
LET A% = ((B% + C%) + D%)
ACHTUNG: Standardmäßig ist der Präprozessor ausgeschaltet. Vor der Nutzung muß er mit
$O+ aktiviert werden! Damit der Präprozessor korrekt funktioniert, dürfen die
Variablennamen weder einen der Operatoren, noch ein Zeichen enthalten, mit denen
Parameter getrennt werden (das sind , ; - > = : und das Leerzeichen). Auch sonst können
diese Zeichen in Variablennamen zu Problemen führen. Derzeit wird das von PROFAN² aber
noch nicht angemeckert. Da der Präprozessor die entsprerchenden Zeilen vor der
Ausführung bzw. vor dem Compilieren übersetzt, können sich Texte in Fehlermeldungen auf
die übersetzte Syntax beziehen.
Seite 27
RGH-PROFAN²
Für schnelle Berechnungen mit Integer-Werten (z.B. in Schleifen, etc.) gibt es in PROFAN²
einige neue Befehle, die schneller und übersichtlicher sind:
INC
DEC
ADD
SUB
V%
V%
V%,n
V%,n
erhöht V% um 1
erniedrigt V% um 1
erhöht V% um n
erniedrigt V% um n
(Hierbei steht V% für eine beliebige Integer-Variable und n für einen beliebigen Ausdruck.)
Für das Zusammenfügen von Strings (Zeichenketten) kann die Funktion @ADD$ verwandt
werden. Es ist aber auch möglich, in einem LET-Befehl verschiedene Strings
zusammenzufügen, indem die Stringausdrücke (wie beim PRINT-Befehl) durch Semikolon
oder Komma getrennt, hintereinandergeschrieben werden. Beispiel:
LET TEXT$ = "Du bist",Alter%,"Jahre alt."
Dabei fügt ein Semikolon die Strings direkt zusammen, während ein Komma ein Leerzeichen
einfügt.
HINWEIS: Die automatische Typumwandlung funktioniert bei einfachen Variablen. Bei
Funktionen, die einen numerischen Wert zurückgeben, wird nicht immer automatisch
umgewandelt, daher ist hier immer die Funktion @Str$ zu verwenden!
Seite 28
RGH-PROFAN²
7 - Variablen, Datentypen und Typen-Umwandlung
Variablen sind Platzhalter, um im Programm gebrauchte Werte zwischenzuspeichern. Je
nach Art des Wertes wird ein bestimmter Datentyp verwandt. PROFAN² kennt fünf
Datentypen: Integer, LongInt, Float, String und Bereich. Wie in PASCAL müssen Variablen
vor ihrer Verwendung deklariert werden. Nur deklarierte Variablen sind bekannt und können
vom folgenden Programm genutzt werden. Das Deklarieren geschieht in PROFAN² mit dem
Befehl "Declare". Wenn der Befehl auch überall im Programm stehen darf, so empfiehlt es
sich doch, alle Declare-Anweisungen am Anfang des Programmes oder der Prozedur zu
stellen. Mehrere Variablen können durch Kommata getrennt mit einem Declare-Befehl
deklariert werden:
Declare Zahl1%, Zahl2!, Text$
Declare Ergebnis&
Der Typ der Variablen wird durch das Postfix (letztes Zeichen des Variablennamens
festgelegt. Der Variablenname darf (inclusive Postfix) 32 Zeichen lang sein und außer dem
Leerzeichen so ziemlich alle Zeichen enthalten. Trotzdem ist dringend zu empfehlen, nur
Buchstaben, Ziffern, Unterstriche und Punkte zu verwenden. Sonst wirds unleserlich.
Damit der Präprozessor für Operatoren korrekt funktioniert, dürfen die Variablennamen
weder einen der Operatoren, noch ein Zeichen enthalten, mit denen Parameter getrennt
werden (das sind , ; - > = : und das Leerzeichen). Auch sonst können diese Zeichen in
Variablennamen zu Problemen führen. Derzeit wird das von PROFAN² aber noch nicht
angemeckert.
In einer Prozedur oder einem Unterprogramm definierte Variablen sind nur in der Prozedur
bekannt. Hingegen sind in einer Prozedur oder einem Unterprogramm auch alle außerhalb
declarierten Variablen bekannt. Hier verhält sich PROFAN eher wie PASCAL. (Das aus
BASIC bekannte SHARED wird nicht benötigt.)
ACHTUNG: Eine Ausnahme bilden die Bereichs- und Arrayvariablen: Diese sind immer
global und überall bekannt!
7.1 Integer
Integervariablen werden, wie in BASIC üblich, durch ein % als Postfix gekennzeichnet.
Integervariablen können Werte von -32768 bis + 32767 annehmen. Wird dieser Wert überoder unterschritten, erfolgt zwar keine Fehlermeldung, aber die Ergebnisse werden
ungewöhnlich sein.
Nur mit Integervariablen können auch die vier Rechenbefehle INC, DEC, ADD und SUB
durchgeführt werden.
HINWEIS: Aus Kompatibilitätsgründen ist auch im 32-Bit-PROFAN² der "offizielle"
Wertebereich eines Integers unverändert von -32768 bis 32767!
Seite 29
RGH-PROFAN²
7.2 LongInt
LongInt-Variablen haben das & als Postfix. Im übrigen gilt für den Variablennamen das
gleiche, wie für Integer. Der Wertebereich geht von -2 Milliarden bis etwas über +2
Milliarden.
7.3 Float
Float heißen jene Variablen, die reelle Zahlen (Fließkomma-Zahlen) aufnehmen können. Die
Rechengenauigkeit ist mindestens 15 Stellen. Ach ja: Das Postfix ist, wie in BASIC, das
Ausrufezeichen. Im Gegensatz zu BASIC darf das Postfix aber niemals weggelassen
werden. Den Versuch, eine Variable ohne Postfix (%, &, !, $) zu declarieren, würde
PROFAN² bemängeln! Soll eine ganze Zahl als Float gekennzeichnet werden (z.B., damit
beim Ausdruck die Nachkommastellen gedruckt werden), ist sie trotzdem als Dezimalbruch
zu schreiben: PRINT 5.0! Wenn PROFAN² auch ein deutsches Produkt ist, so wird trotzdem
der Dezimalpunkt verwandt.
7.4 String
Strings werden durch ein $ am Ende des Dateinamens gekennzeichnet und können maximal
255 Zeichen lang sein. Stringkonstanten werden durch Anführungszeichen eingeschlossen:
LET Text$="Teststring"
Für einige nicht direkt über die Tastatur eingebbare Zeichen gibt es nun (ähnlich wie in C)
Ersatzzeichen. Dabei steht "\a" für @Chr$(8), "\t" für @Chr$(9) und "\n" für @Chr$(13). Das
erleichtert z.B. die Formatierung von Messageboxen und Menüs erheblich. Um z.B. die
Anzeige von Funktionstasten in Menüs auszurichten, reicht es jetzt zum Beispiel, folgende
Zeile einzugeben:
APPENDMENU 124,"Hilfe\tF1"
Mit "\a" kann ein Menüpunkt in der Menüzeile ganz nach rechts positioniert werden, wie es
häufig unter Windows 3.x bei der Hilfe der Fall ist:
APPENDMENUBAR "\aHilfe"
(Dies funktioniert nur in der 16-Bit-Version von PROFAN² und ist auch sonst unter Windows
95 nicht mehr üblich.)
Mit "\n" erzielen Sie in Messageboxen einen Zeilenumbruch genau dort, wo Sie ihn haben
wollen.
Will man aber nun wirklich z.B. die Zeichenfolge "\a" im String verwenden, muß man den
Backslash verdoppeln: "\\a". Es ist empfehlenswert, in Literalen (Strings zwischen zwei ")
grundsätzlich für einen Backslash den doppelten Backslash einzugeben! (Aus Kompatibelität
zu älteren PROFAN²-Versionen gilt: Auch "\." wird als "\" wiedergegeben.)
HINWEIS: Bei Funktionen oder Befehlen, die einen Dateinamen (evt. mit Pfad) oder Pfad
erwarten, werden die Ersatzzeichen nicht berücksichtigt, wenn der Datei- bzw. Pfadname ein
Literal ist (in Anführungszeichen steht).
Seite 30
RGH-PROFAN²
7.5 Bereich
Bereichsvariablen werden durch ein # am Ende des Dateinamens gekennzeichnet:
DECLARE Bereich#
Diese Variable ist ein Zeiger auf einen Datenbereich. Man könnte auch sagen, sie ist ein
Handle für einen Datenbereich. Der Wert der Variablen selbst kann zwar mit PRINT
ausgegeben oder mit LET einer LongInt-Variable zugewiesen werden, ist aber für den
Programmierer ohne Bedeutung. Die Variable kommt unter Anderem dort zum Einsatz, wo
z.B. Messages Zeiger auf Datenstrukturen (meist Zeichenketten) verlangen. Außerdem kann
sie in vielen Fällen auch als Ersatz für die aus anderen Sprachen gewohnten Arrays dienen.
ACHTUNG: Da Bereichsvariablen grundsätzlich global sind, muß die Deklaration im
Hauptprogramm erfolgen. Eine Deklaration in einer Prozedur würde beim zweiten Aufruf eine
Fehlermeldung erzeugen.
Bevor der Speicherbereich, auf den die Variable zeigt, benutzt werden kann, muß er mit DIM
Name#,Groesse& bereitgestellt werden. Groesse& muß in der 16-Bit-Version von PROFAN²
einen Wert zwischen 1 und 64500 haben. Beispiel:
DIM Bereich#,32000
Mit BYTE Name#,A&=Wert& wird dem Byte an der Adresse A& im Speicherbereich Name#
ein Wert zugewiesen. Die Adressbereich geht von 0 bis Groesse-1, anderenfalls erfolgt eine
Fehlermeldung. Der Wert liegt hier zwischen 0 und 255. Weitere Befehle, um den Speicher
zu belegen sind WORD, LONG, CHAR und STRING.
Mit der Funktion @BYTE(Name#,A&) kann die Bereichsvariable ausgelesen werden.
Weitere Funktionen zum Auslesen des Speicherbereiches Name# sind @WORD, @LONG,
@CHAR und @STRING.
BYTE Bereich#,0 = 56
BYTE Bereich#,1 = 251
BYTE Bereich#,31999 = 216
PRINT @BYTE(Bereich#,0)
PRINT @BYTE(Bereich#,1)
PRINT @BYTE(Bereich#,31999)
Mit @BLOCKREAD lesen Sie den Inhalt von Dateien in Bereichsvariablen ein und mit
BLOCKWRITE können Sie den Inhalt einer Bereichsvariablen in eine Datei schreiben.
Keine Angst: Im Gegensatz zu allen anderen Sprachen bei der Verwendung von Zeigern
(bzw. Pointern) achtet PROFAN darauf, daß Sie den mit DIM eingestellten Datenbereich
nicht überschreiten oder gar eine Bereichsvariable nutzen, der noch kein Bereich zugewiesen
wurde.
Jeder mit DIM angeforderte Speicherbereich muß mit DISPOSE Name# nach Gebrauch
wieder freigegeben werden:
DISPOSE Bereich#
DIM und DISPOSE dürfen auch in einer Prozedur vorkommen. Wenn allerdings ein DIM in
einer Prozedur vorkommt muß diese Bereichsvariable auch mit DISPOSE wieder innerhalb
der Prozedur freigegeben werden. freigegeben werden. Ansonsten ist beim erneuten Aufruf
der Prozedur kein DIM mehr möglich! Beispiel:
Seite 31
RGH-PROFAN²
DECLARE Bereich#
PROC Test
Parameters Groesse%
DIM Bereich#,Groesse%
<... weiterer Programmcode ...>
DISPOSE Bereich#
ENDPROC
' Hauptprogramm
Test 250
Test 30
Test 500
END
Es gibt auch noch den Befehl READTEXT, der eine komplette (kleinere) Textdatei in eine
Bereichsvariable einlesen kann.
ACHTUNG: Wenn Sie allerdings bei einer Message, die als Parameter einen Zeiger auf
Daten/Strings verlangt, anstelle einer Bereichsvariablen eine LongInt-Variable verwenden,
können Sie Ihren Computer zum Absturz bringen und dadurch Datenverluste verursachen!
Das ist auch möglich, wenn eine Bereichsvariable zu klein dimensioniert wurde. Hingegen
kann eine nicht dimensionierte Bereichsvariable (Null-Zeiger) nicht verwandt werden. Es
erfolgt in diesem Fall eine Fehlermeldung.
Seite 32
RGH-PROFAN²
7.6 Typen-Umwandlung
Die Umwandlung der verschiedenen Variablentypen in andere erfolgt zumeist automatisch,
wenn ein Literal oder eine Variable einer Variablen zugewiesen werden. Bei einer Rechnung
oder Zuweisung wird dann das Ergebnis automatisch in den Typ der Variable, der das
Ergebnis zugewiesen wird, umgewandelt. Wenn Zahl1! den Wert 5.678 hätte, würde bei
LET Zahl2% = Zahl1!
der Variablen Zahl2% der Wert 5 zugewiesen.
PRINT Zahl2%
würde auf jeden Fall den Wert als Dezimalwert ausgeben, ebenso
LET Text$=@STR$(Zahl2%)
oder auch
LET Text$=Zahl2%
(Ja, das geht auch!). Mit der Funktion @INT können Sie jedoch bewußt die
Nachkommastellen abschneiden:
PRINT @INT(Zahl2%)
Die Funktion @INT schneidet bei einer Zahl die Nachkommastellen ab. Das Ergebnis kann
jedoch - wie immer - jedem Variablentyp zugewiesen werden, bevorzugt natürlich einer
Integer- oder LongInt-Variablen.
Die Funktion @STR$ verwandelt einen numerischen Wert in einen String, wobei bezüglich
der Formatierung die Einstellungen mittels DECIMALS und NUMWIDTH berücksichtigt
werden. Die Funktion wird also häufig bei formatierter Zahlenausgabe Verwendung finden.
Wird keine Formatierung gewünscht, kann das @STR$ auch weggelassen werden.
Besonders viele Möglichkeiten der Umwandlung eines Zahlenwertes in einen String bietet die
Funktion @FORMAT$, bei der für eine Zahl bis zu drei verschiedene Formatierungen
angegeben werden können, jenachdem ob der Wert kleiner als 0, größer als 0 oder exakt 0
ist. Auch die wissenschaftliche Darstellung und die Währungsdarstellung wird beherrscht.
Der Funktionsumfang geht über den der BASIC-Anweisung USING weit hinaus.
Die Funktion @VAL ermittelt den numerischen Wert eines Strings. Kann der String nicht
komplett umgewandelt werden, wird der Wert 0 angenommen. Eine Fehlermeldung oder
Warnung erfolgt nicht. Das @VAL kann oft auch weggelassen werden:
LET Zahl% = Text$
Selbst eine Zeile
LET Zahl% = Maier
würde funktionieren. Die Zahl erhielte dann den Wert 0. Wenn die Warnungen mit
"SETERRORLEVEL 1" eingeschaltet sind, würde in diesem Fall jedoch eine Warnung darauf
hinweisen, daß "Maier" nicht als Zahl zu interpretieren ist. Diese Warnung erscheint immer
dann, wenn Interpreter oder Runtime einen Ausdruck nicht interpretieren können, also auch
dann, wenn ein String erwartet wird, aber etwas da steht, was weder String noch numerischer
Wert ist. (Warum? Nun: Wenn kein String - erkennbar durch Anführungszeichen - gefunden
wird, versucht PROFAN² eine Zahl zu lesen, um diese dann intern in einen String
umzuwandeln.)
Seite 33
RGH-PROFAN²
Ich ziehe es vor, die Umwandlungen zwischen Strings und numerischen Werten immer mit
@VAL und @STR$ zu programmieren. Das macht die Programme lesbarer. Außerdem gibt
es häufig dann keine automatische Typumwandlung, wenn in der Zuweisung Ergebnisse aus
Funktionen vorkommen.
Von der Typumwandlung ausgeschlossen bleiben natürlich die Bereichsvariablen. Zwar kann
eine Bereichsvariable einer LongInt-Variablen zugewiesen werden, aber dieser Wert stellt
nur den Zeiger auf den Datenbereich dar und ist daher für den Programmierer nicht nutzbar.
(Ausnahme: Man benutzt diesen Zeiger dann in einer @SENDMESSAGE-Funktion. Aber da
hätte man auch die Bereichsvariable benutzen können.)
7.7 Zahlensysteme
Bisher konnte PROFAN lediglich hexadezimale Zahlen (mit vorangestelltem "$") verarbeiten.
Auch @VAL konnte damit schon umgehen. Ab Version 6.0 sind die Möglichkeiten der
Zahlendarstellung und -umrechnung gewaltig erweitert worden: Mit "%" werden binäre Zahlen
eingeleitet und mit "&" Zahlen im oktalen System:
LET Zahl1& = $F0AE
LET Zahl2& = &01734
LET Zahl3& = %01001011001
Auch die @VAL-Funktion kann mit den neuen Typen umgehen:
LET A$ = "%0101"
LET A% = @VAL(A$)
Der Wertebeeich für Zahlen in hexadezimaler, oktaler oder binärer Darstellung beträgt den
einer Longint-Variablen.
Neu hinzugekommen sind Funktionen, um Werte auch entsprechend darstellen zu können.
Diese Funktionen wandeln einen Wert in einen entsprechenden String um: @HEX$, @OCT$
und @BIN$:
PRINT @HEX$(255), \
@OCT$(255), \
@BIN$(255)
ACHTUNG: Der Ergebnisstring enthält nur die "Ziffern" des anderen Zahlensystems, nicht
aber das Kennzeichen "$", "&" oder "%". Dieses muß bei Bedarf noch vorangestellt werden.
Um mit binären Zahlen noch besser umgehen zu können, wurden zwei Bit-Funktionen
hinzugefügt. Mit @TESTBIT kann man in Erfahrung bringen, ob das gewünschte Bit gesetzt
ist oder nicht. Mit @SETBIT kann man ein spezielles Bit setzen:
LET A% = %0020
PRINT @TESTBIT(A%,3)
LET A% = @SETBIT(A%,3,1)
PRINT A%
WICHTIG: Die Zählung der Bitposition beginnt 0.
Seite 34
RGH-PROFAN²
8 - Arrays
Arrays in der von BASIC oder PASCAL gewohnten Form gibt es in PROFAN² erst seit
Version 6.0. Vorher gab es (und gibt es aus Kompatibilitätsgründen immer noch) lediglich
eine Liste mit max. 16383 Elementen (0 .. 16382) je Datentyp in der 16-Bit-Version bzw.
max. 32768 Elemente (0 .. 32767) in der 32-Bit-Version von PROFAN². Um diese Listen von
den wirklichen Arrays zu unterscheiden, verwende ich im Folgenden den Begriff "Liste".
8.1 Je Datentyp eine Liste
Dimensioniert werden diese Listen mit den Befehlen DIM%, DIM!, DIM& und DIM$. Mit dem
Befehl
DIM% 499
wird eine Integerliste mit 500 Elementen definiert. Jeder dieser vier DIM-Befehle darf nur
einmal während des Programmlaufes vorkommen und zwar zeitlich vor dem ersten Zugriff
auf ein Element der entsprechenden Liste. Es ist sinnvoll, die DIM-Befehle an den Anfang
des Programmes zu stellen. Nachträgliche Vergrößerung der Liste ist ebensowenig möglich,
wie ein Löschen und Neudefinieren.
Zum Füllen der Listen werden die Befehle LIST%, LIST!, LIST& und LIST$ verwandt. Mit der
Zeile
LIST& 99 = 120000
würde ich dem 99. Element der LongInt-Liste den Wert 120000 zuweisen. Ist die Liste nicht
definiert oder ist 99 außerhalb der definierten Größe, erfolgt eine Fehlermeldung.
Um den Inhalt eines Listen-Elementes zu lesen, wird je nach Typ einer der Funktionen
@LIST%. @LIST!, @LIST& oder @LIST$ verwandt. Wenn ich den Inhalt des 34. Elementes
der Stringliste der Variable Test% zuweisen möchte, verwende ich die Zeile:
LET Test$ = @LIST$(34)
Der DIM-Befehl ohne Datentypkennung gehört nicht hierher, da mit ihm eine
Bereichsvariable dimensioniert wird. Andererseits läßt sich sicher in vielen Fällen, in denen
in anderen Programmmiersprachen ein Array eingesetzt wird, eine Bereichsvariable
verwenden. Ein Bereich kannn durchaus als ein Array (mit nahezu beliebiger Größe bzw.
max. 64 kByte in der 16-Bit-Version) betrachtet werden. So können mit Bereichsvariablen
problemlos Byte- und IntegerArrays simuliert werden.
8.2 Mehrdimensionale Arrays
Hier handelt es sich um Arrays, wie sie z.B. von BASIC oder PASCAL her bekannt sind. Die
meisten Probleme ließen sich auch mittels der einen Liste pro Datentyp erledigen, aber die
Arrays sind sicher komfortabler.
Eine Einschränkung soll nicht unerwähnt bleiben: Die neuen Arrays sind, ebenso wie die
Bereichsvariablen, global. Der Speicherplatz eines einmal deklarierten Arrays wird erst bei
Programmende wieder freigegeben. Wird ein Array ein weiteres Mal mit gleichem Namen
und Typ deklariert, kann immer nur auf das zuletzt deklarierte Array zugegriffen werden. Es
empfiehlt sich daher, alle im Programm genutzten Arrays am Anfang des Programmes
zusammen mit den übrigen globalen Variablen zu deklarieren.
Es können Arrays der Datentypen Float, Longint, Integer und String deklariert werden. Ein
Array kann maximal drei Dimensionen aufweisen. Die Elemente aller Arrays eines Datentyps
dürfen 32000 (32 Bit) bzw. 16000 (16 Bit) nicht überschreiten.
Seite 35
RGH-PROFAN²
Erzeugt werden Arrays mit dem DECLARE-Befehl, indem die Anzahl der Elemente und
Dimensionen in eckigen Klammern mit angegeben wird:
DECLARE Spielfeld%[8,8]
Hier wird ein zweidimensionales Integer-Array aus 8 * 8 Elementen - etwa für ein
Schachspiel - erzeugt.
Im nächsten Beispiel erzeugen wir ein Array, um einen
dreidiensionalen Würfel mit der Kantenlänge 25 zu beschreiben:
DECLARE Wuerfel&[25,25,25]
Zuweisungen und Zugriffe erfolgen wie bei anderen Variablen auch, nur daß bei Arrays in
eckigen Klammern angegeben wird, auf welches Element ich zugreifen möchte:
LET Spielfeld%[5,4] = Koenig%
LET Wuerfel&[x%,y%,z%] = 0
LET Wert% = Spielfeld%[x%,y%]
PRINT Wuerfel&[10,5,9]
HINWEIS: Die bisherigen eindimensionalen Listen je Datentyp existieren zusätzlich (!)
weiterhin!
Seite 36
RGH-PROFAN²
9 - Kontrollstrukturen
PROFAN² bietet im wesentlichen die aus anderen Sprachen bekannten Kontrollstrukturen:
Case / CaseNot
If / IfNot
While / WhileNot
@If
Aus Gründen der Kompatibilität zu frühesten PROFAN²-Versionen gibt es auch noch die
Befehle GOSUB und GOTO, die aber in künftigen PROFAN²-Versionen ebensowenig
unterstützt werden, wie heute schon vom Support.
9.1 CASE / CASENOT
Der CASE-Befehl stellt letztlich ein einzeiliges IF dar:
CASE @Equ(A%,3) : PRINT "A hat den Wert 3"
Der hinter dem CASE stehende Befehl bzw. Prozeduraufruf wird nur ausgeführt, wenn der
Ausdruck vor dem Doppelpunkt einen von Null verschiedenen Wert hat, d.h. wenn die
Bedingung erfüllt wird. Ist die Bedingung nicht erfüllt, geht es direkt mit der nächsten Zeile
weiter. Eine Sonderform des CASE ist die Form CASENOT:
CASENOT @Equ(A%,3) : PRINT "A ist ungleich drei"
Dies ist lediglich eine bequemere (und in der Ausführung schnellere) Schreibweise der Zeile
CASE @Not(@Equ(A%,3)) : PRINT "A ist ungleich drei"
9.2 IF / IFNOT ...
Mit Ausnahme der Sonderform IFNOT, die für IF @Not steht, gilt hier das aus BASIC
Bekannte: Die nach IF bzw. IFNOT stehenden Zeilen werden ausgeführt, wenn der
Bedingungsausdruck hinter dem IF bzw. IFNOT ungleich 0 ist. Lediglich das THEN gibt es in
PROFAN² nicht und wird weggelassen:
IF @Equ(A%,1)
PRINT "A ist gleich 1"
ENDIF
WICHTIG: Hinter der Bedingung darf (außer einer Anmerkung mit ') kein Befehl stehen. Das
in BASIC und PASCAL bekannte einzeilige IF wird in PROFAN² durch CASE ersetzt. Zu
jedem IF muß es ein entsprechendes ENDIF geben!
Natürlich gibt es in PROFAN² auch den ELSE-Zweig, der ausgeführt wird, wenn die
Bedingung nicht erfüllt wird:
IF @Equ(A%,1)
PRINT "A ist gleich 1"
PRINT "--------------"
ELSE
COLOR 5,15
PRINT "A ist ungleich 1"
ENDIF
Seite 37
RGH-PROFAN²
Auch eine Abfrage auf mehrere Bedingungen (z.B. bei der Auswertung eines Menüs) ist mit
ELSEIF möglich. Sobald eine Bedingung erfüllt ist, wird der zugehörige Programmteil
abgearbeitet und anschließend mit der Zeile nach dem ENDIF fortgefahren. Die SELECTund CASE-Strukturen anderer Sprachen lassen sich somit abbilden:
IF @Lt(A%,1)
COLOR 1,15
PRINT "A ist
ELSEIF @Equ(A%,1)
COLOR 2,15
PRINT "A ist
ELSEIF @Equ(A%,2)
COLOR 3,15
PRINT "A ist
ELSE
PRINT "A ist
ENDIF
kleiner als 1"
gleich 1"
gleich 2"
größer als 2"
Dieser Programmteil wäre identisch mit folgender Struktur:
IF @Lt(A%,1)
COLOR 1,15
PRINT "A ist kleiner als 1"
ELSE
IF @Equ(A%,1)
COLOR 2,15
PRINT "A ist gleich 1"
ELSE
IF @Equ(A%,2)
COLOR 3,15
PRINT "A ist gleich 2"
ELSE
PRINT "A ist größer als 2"
ENDIF
ENDIF
ENDIF
9.3 WHILE / WHILENOT
Selbstverständlich gibt es auch Schleifen in PROFAN². Der zwischen WHILE und WEND
stehende Programmteil wird solange ausgeführt, solange die Bedingung erfüllt ist. Auch bei
WHILE ist die Zusammenziehung mit @Not zu WHILENOT erlaubt. Ebenso wie bei
Unterprogrammen/Prozeduren ist eine Schachtelungstiefe von 10 erlaubt. In der Praxis
dürfte dieser Wert kaum erreicht werden. Ein Beispiel für eine WHILE-Schleife:
LET A%=0
WHILENOT @Equ(A%,10)
INC A%
PRINT A%;" zum Quadrat ist ";@Squ(A%)
ENDWHILE
Anstelle von ENDWHILE ist auch die von BASIC her gewohnte Schreibweise WEND erlaubt.
Aber analog zu den Befehlspaaren IF - ENDIF und PROC - ENDPROC ist die Verwendung
der Schreibweise ENDWHILE logischer und für den nicht von BASIC her kommenden
PROFAN²-Programmierer leichter zu merken.
Seite 38
RGH-PROFAN²
9.4 @IF
In Anlehnung an C gibt es das IF auch als Funktion. Die Funktion @IF hat drei Argumente:
Das erste Argument ist die Bedingung; das zweite Argument ist der Wert, der zurückgegeben
wird, wenn die Bedingung erfüllt ist und das dritte Argument ist schließlich der Wert, der bei
unerfüllter Bedingung zurückgegeben wird. Beispiele:
LET Text$ = @IF(@Equ(A%,1), "A ist gleich 1", \
"A ist ungleich 1")
PRINT Text$
LET A% = @IF(@Gt(A%,1000), @Add(A%,200), @Add(A%,50) )
PRINT A%
Im zweiten Beispiel wird zu A% 200 addiert wenn es größer als 1000 ist; im anderen Fall
kommen nur 50 dazu.
Seite 39
RGH-PROFAN²
10 - Prozeduren
Prozeduren sind Unterprogramme, die wie neue Befehle behandelt werden können.
Unterprogramme mit GOSUB werden daher in Zukunft weder notwendig noch erlaubt sein,
da Prozeduren deutlich leistungsfähiger sind:
Eine Prozedur wird einmal - vor ihrer ersten Verwendung - definiert und kann dann jederzeit
wie ein neuer Befehl im Programm verwandt werden. Es ist sinnvoll, alle
Prozedurdefinitionen vor dem Beginn des Programmes (nach den DECLARE-, DIM-, und
DEF-Befehlen) durchzuführen. Häufig verwandte Funktionen (s.u.) und Prozeduren kann
man in einer Include-Datei (s.o.) zusammenfassen und sich so beliebige
Spracherweiterungen selbst programmieren.
Eine Prozedur-Definition beginnt mit dem Befehl PROC, gefolgt vom Namen der Prozedur.
Die Definition endet mit der Zeile ENDPROC. Eine Prozedur wird natürlich während Ihrer
Definition nicht ausgeführt, sondern erst, wenn Sie aufgerufen wird. Hier ein komplettes MiniProgramm als Beispiel für eine sehr einfache Prozedur:
'Testprogramm
'-----------PROC Titelzeile
PRINT "Das ist der Titel"
ENDPROC
CLS
PRINT "Das ist noch vor der Prozedur."
TITELZEILE
PRINT "Das ist nach der Prozedur."
WAITKEY
END
Einer Prozedur können auch Parameter übergeben werden. Diese werden mit dem Befehl
PARAMETERS in die Prozedur übernommen: Dem Befehl folgen die Variablen, denen die
Parameter zugewiesen werden. Diese Variablen - wie alle in der Prozedur declarierten
Variablen - sind "LOKAL", d.h. sie sind nur in der Prozedur dem System bekannt. Alle
außerhalb der Prozedur bekannten Variablen sind in der Prozedur auch bekannt (es sei
denn, es gibt lokale Variablen mit gleichem Namen).
ACHTUNG: Bereichsvariablen und Arrays können NICHT als Prozedurparameter verwandt
werden, da diese immer global sind.
Ein Beispiel, bei dem eine Prozedur definiert wird, die eine Text wiederholt ausgibt:
Testprogramm 2
'-------------PROC Wiederhole
PARAMETERS Anzahl%, Text$
DECLARE I%
LET I% = 0
WHILE @Lt(I%,Anzahl%)
PRINT Text$
ENDWHILE
ENDPROC
CLS
PRINT "Das ist noch vor der Prozedur."
WIEDERHOLE 5, "Testtext"
PRINT "Das ist nach der Prozedur."
WAITKEY
END
Seite 40
RGH-PROFAN²
Die Parameter, die der Prozedur übergeben werden, werden durch Kommata voneinander
getrennt. Die Typen und die Anzahl der Parameter werden von PROFAN² nicht überprüft,
obwohl sich die Anzahl über die Systemvariable %PCOUNT ermitteln läßt. Es sind maximal
12 Parameter erlaubt. Selbstverständlich können in Prozeduren wieder neue Prozeduren
definiert werden. Diese sind dann natürlich auch nur lokal bekannt. Hier gilt sinngemäß das
Gleiche, wie für Variablen.
Eine Prozedur kann in PROFAN² auch einen Wert zurückgeben: Innerhalb der Prozedur darf
der RETURN-Befehl vorkommen, wenn die Prozedur vor dem ENDPROC verlassen werden
soll. Dem RETURN kann ein Parameter zurückgegeben werden, der je nach Typ mit der
Funktion @$(0), @%(0), @&(0) oder @$(0) gelesen werden kann. (Diese Funktionen sind
der "Parameterstack" von PROFAN². Für jeden Datentyp gibt es die Parameter 0 bis 12,
wobei der 0. Parameter den Rückgabewert und die übrigen die übergebenen Parameter
enthalten. Im obigen Beispiel könnte also auch über @$(2) auf den übergebenen Text
zugegriffen werden.) Ein Beispiel für die Rückgabe eines Wertes aus einer Prozedur:
'Testprogramm 3
'-------------PROC Titelzeile
PRINT "Das ist der Titel"
RETURN "Ok"
ENDPROC
CLS
PRINT "Das ist noch vor der Prozedur."
TITELZEILE
PRINT "Das ist nach der Prozedur: ";@$(0)
WAITKEY
END
Auch wenn eine Prozedur mit RETURN verlassen wird, darf das ENDPROC nicht fehlen!
Seite 41
RGH-PROFAN²
11 - Funktionen
In PROFAN² gibt es zahlreiche "eingebaute" Funktionen. Zusätzlich gibt es die Möglichkeit
eigene Funktionen zu definieren. Auch der Zugriff auf die Funktionen des Windows-API oder
anderer DLLs ist möglich.
11.1 Funktionen - Grundlagen
Eine Funktion gibt einen Wert zurück, der in der Regel von den Parametern der Funktion
abhängig ist. Überall da, wo in PROFAN² Variablen oder konstante Werte (Literale)
eingesetzt werden können, dürfen auch Funktionen stehen. Der Rückgabewert der Funktion
sollte der gleiche Typ sein, wie der erwartete Wert.
Alle Funktionsnamen in PROFAN² beginnen normalerweise mit einem @. Während viele
Anwender mit mir der Meinung sind, daß das @ den Quellccode übersichtlicher macht,
indem die Funktionen sofort erkennbar sind, gibt es auch einige, denen die Eingabe des @
(über <AltGr><Q>) zu umständlich ist. Ab der PROFAN²-Version 4.0 ist es möglich das @
überall (auch beim Parameterstack) wegzulassen. Im Interpretermodus kann dies zu
Geschwindigkeitseinbußen führen. Die Performance der compilierten Programme ist davon
unbeeinflußt. Im Handbuch wird durchgängig das @ als Funktionskennzeichen verwandt.
Funktionen, deren Funktionsnamen mit dem $ endet, geben in vielen Fällen einen String
zurück, die übrigen Funktionen einen numerischen Wert. In einigen Fällen enden auch
Vergleichsfunktionen, die entweder 1 oder 0 zurückgeben mit einem $, um deutlich zu
machen, das hiermit Strings verglichen werden.
Wenn der Rückgabewert einer Funktion uninteressant ist, kann die Zuweisung auch
weggelassen werden. Bis auf die immer noch notwendigen Klammern, wird die Funktion
dann wie ein Befehl verwandt.
Beispiel:
@LISTBOX$("Das ist die Liste",0)
In diesem Fall wird die Listbox nur zum Anschauen angezeigt oder aber das Ergebnis der
Auswahl über die Systemvariable $GETTEXT gelesen.
Seite 42
RGH-PROFAN²
11.2 Allgemeine Funktionen
Neben den in PROFAN² zahlreich vertretenen Spezialfunktionen, die in den jeweiligen
Kapiteln Erwähnung finden, gibt es auch eine ganze Reihe allgemeiner Funktionen zur
Bearbeitung von Zeichenketten (Strings) und zur Verarbeitung mathematischer Formeln:
Mathematische Funktionen:
@Abs
@Add
@And
@ArcTan
@Cos
@Cot
@Div&
@Div
@Equ
@Exp
@GT
@Int
@Lg
@Ln
@LT
@Mod
@Mul
@Neq
@Not
@Or
@Pi
@Pow
@Rnd
@Round
@Sin
@Sqr
@Sqrt
@Sub
@Tan
- Absolutwert
- Addition (+)
- logisches Und
- ArcusTangens
- Cosinus
- Cotangens
- ganzzahlige Division (\)
- Division (/)
- Vergleich: Gleichheit
- Exponentialfunktion
- Vergleich: Größer
- Integer (Ganzzahl)
- Dekadischer Logarithmus
- Natürlicher Logarithmus
- Vergleich: Kleiner
- Modulo-Funktion
- Multiplikation (*)
- Vergleich: Ungleichheit
- logisches Nicht
- logisches Oder
- Kreiszahl
- Potenz-Funktion (^)
- Zufallszahl
- Rundungsfunktion
- Sinus
- Quadrat
- Quadratwurzel
- Subtraktion (-)
- Tangens
Seite 43
RGH-PROFAN²
Zeichenketten-Funktionen:
@Add$
@AnsiToOem$
@Bin$
@Chr$
@CToD$
@Del$
@DToC$
@Equ$
@GT$
@Hex$
@Ins$
@InStr
@Len
@Left$
@Lower$
@LT$
@Mid$
@MkStr$
@NEq$
@Oct$
@OemToAnsi$
@Ord
@Space$
@Str$
@SubStr$
@Right$
@Translate$
@Trim$
@Upper$
@Val
- Zusammenfügen
- Ansi -> ASCII
- Binär -> String
- Zeichen
- Datumsformat umwandeln
- Teilstring löschen
- Datumsformat umwandeln
- Vergleich: Gleichheit
- Vergleich: Größer
- Hexadezimal -> String
- Teilstring einfügen
- Teilstringposition finden
- Länge eines Strings
- linker Teilstring
- in Kleinbuchstaben wandeln
- Vergleich: Kleiner
- Teilstring ermitteln
- Wiederholstring
- Vergleich: Ungleichheit
- Octal -> String
- ASCII -> Ansi
- Zeichencode (ASC)
- String aus Leerrzeichen
- Wert in String umwandeln
- String in Teilstrings zerlegen
- rechter Teilstring
- Stringteile ersetzen
- Leerzeichen entfernen
- in Großbuchstaben wandeln
- String in numerischen Wert umwandeln
Nähere Hinweise zur Syntax entnehmen Sie bitte der Referenz.
Seite 44
RGH-PROFAN²
11.3 Definierte Funktionen
PROFAN² bietet auch die Möglichkeiten, selbst Funktionen zu definieren, die im Programm
wie die eingebauten Funktionen verwandt werden können. Eine Funktionsdefinition beginnt
mit dem Befehlswort DEF. Diesem folgt der Name der Funktion, der natürlich wie alle
PROFAN²-Funktionen mit einem @ beginnen kann. (Das @ erreicht man im Übrigen mit der
Tastenkombination <AltGr><Q>.) Nach dem Namen folgt in Klammern die Anzahl der
Parameter. Dann kommt der Ausdruck, der die Funktion beschreibt. Die Funktionsparameter
werden über den "Parameterstack" (s.o. unter Prozeduren) übergeben. Mit @$(n), @%(n),
@&(n) bzw. @!(n) werden die Parameter gelesen, wobei n für die Nummer des Parameters
(von 1 - 12) steht. Ein Beispiel für eine Funktion zur Errechnung der dritten Potenz einer
Zahl:
DEF @Pot3(1)
@Mul(@Squ(@!(1)),@!(1))
Das Quadrat des ersten Parameters wird mit dem Parameter multipliziert. Aufgerufen wird
die Funktion, wie jede andere auch:
LET I% = 0
WHILE @Lt(I%,10)
INC I%
PRINT I%;"³ = ";@Pot3(I%)
WEND
Als zweites Beispiel dient eine Funktion, die die ersten n Zeichen eines Strings zurückgibt.
Nennen wir sie LINKS$ und definieren wir sie uns:
DEF @Links$(2) @Mid$(@$(1),1,@%(2))
Wenden wir Sie an:
DECLARE A$
LET A$ = "Testbild"
PRINT @Links$(A$,4)
(Gewiß, ab PROFAN² 6.0 gibt es die Funktion LEFT$, die das Gleiche macht, aber das
Beispiel ist eben schon etwas älter ...)
Auch hier findet bewußt keine Typüberprüfung statt, da alle Typen automatisch ineinander
umgewandelt werden. Sehr wohl überprüft wird aber die Anzahl der Parameter! Wie bei allen
anderen Funktionen erfolgt eine Fehlermeldung, wenn zuwenig oder zuviel Parameter
angegeben werden.
Unter Verwendung der @IF-Funktion und/oder der Dialogbox-Funktionen sind sehr komplexe
Funktionsdefinitionen möglich. Funktionsdefinitionen über mehrer Programm-Zeilen werden
von PROFAN² nicht unterstützt.
Seite 45
RGH-PROFAN²
11.4 Externe Funktionen
Ab PROFAN² 4.2 ist es nun auch möglich, externe Funktionen (beliebige DLLs und
Windows-API) zu definieren. HINWEIS: Auch in der 32-Bit-Version können externe
Funktionen aus 16-Bit-DLLs bzw. der 16-BIT-API verwandt werden. Dafür ist für die
Kommunikation zwischen 16- und 32-Bit-Welt das Programm PROF16.EXE verantwortlich,
das bei der Installation in Ihr Windows-Verzeichnis kopiert wurde. Diese Möglichkeit ist
jedoch als Notbehelf zu betrachten, da der Aufruf sehr langsam ist und auch bei einigen
wenigen Funktionen nicht korrekt funktioniert. 32-Bit-Funktionen können ausschließlich mit
der 32-Bit-Version von PROFAN² aufgerufen werden.
Auch hier wird der für Funktionsdefinitionen zuständige Befehl DEF verwandt: Hinter dem
DEF folgt wie gewohnt der freigewählte Name (der natürlich keinem Namen einer PROFAN²Funktion entsprechen darf) und in Klammern die Anzahl der Parameter (max. 12) der neuen
Funktion.
Dann folgt gekennzeichnet durch ein vorangestelltes "*" (16-Bit-Funktion) oder "!" (32-BitFunktion) ein String mit dem Namen der DLL und der Name der Funktion in der DLL (Groß/Kleinschreibung beachten). Beim Aufruf einer 16-Bit-Funktion folgen nun die Beschreibung
der Parametertypen und die Beschreibung des Ergebnistyps.
Bei den Parametertypen bedeuten:
% = Integer (auch Handles, Words, Bytes und Boolsche Werte sind so zu kennzeichnen)
& = LongInt (auch unsigned Long und alle anderen 4-Byte-Werte)
# = Bereich (hierunter fallen alle Zeiger auf Strings, Datenstrukturen, etc.)
Beim Ergebnistyp bedeutet:
% = Integer (Handles, Words, Bytes, boolsche Werte)
& = LongInt (4-Byte-Werte)
Leerstring (kein Ergebniswert)
Bereichsvariablen dienen dazu, Strings oder Datenstrukturen an die externe Funktion zu
übergeben und/oder von ihr zu bekommen. Natürlich sind sie ausreichend zu
dimensionieren.
Bei 32-Bit-Funktionen erübrigt sich die Beschreibung der Parametertypen und des
Ergebnistyps, da alle von PROFAN unterstützten Parameter exakt 4 Byte groß sind.
Beispiele für Aufrufe in der 16-Bit-API:
DEF
DEF
DEF
DEF
DEF
DEF
DEF
@MoveWindow(6) *"USER","MoveWindow","%%%%%%",""
@waveOutGetNumDevs(0) *"MMSYSTEM","waveOutGetNumDevs","","%"
@GetWText(3) *"USER","GetWindowText","%#%","&"
@GetApiPixel(3) *"GDI","GetPixel","%%%","&"
@GetSysResources(1) *"USER","GetFreeSystemResources","%","%"
@MsgBox(4) *"USER","MessageBox","%##%","%"
@GetClientRect(2) *"USER","GetClientRect","%#",""
Beispiele für Aufrufe in der 32-Bit-API:
DEF
DEF
DEF
DEF
DEF
DEF
@MoveWindow(6) !"USER32","MoveWindow"
@waveOutGetNumDevs(0) !"WINMM","waveOutGetNumDevs"
@GetWText(3) !"USER32","GetWindowTextA"
@GetApiPixel(3) !"GDI32","GetPixel"
@MsgBox(4) !"USER32","MessageBoxA"
@GetClientRect(2) !"USER32","GetClientRect"
Seite 46
RGH-PROFAN²
Drei ausführlich dokumentierte Beispielprogramme finden sich im Verzeichnis BEISPIEL:
DLL16.PRF, DLL32.PRF (nur 32-Bit-Version) und RES.PRF. Letzteres ermittelt die freien
Systemresourcen und zeigt sie in einer Messagebox an.
Seite 47
RGH-PROFAN²
12 - Resourcen
Seit Version 5.0 kann PROFAN² auch auf Resourcen in DLLs und EXE-Dateien zugreifen.
12.1 Allgemeines zu Resourcen
Was sind Resourcen?
Resourcen sind "Vorräte", zur Verfügung stehende Dinge, die man gegebenenfalls nutzen
kann. Unter Windows (auch unter OS/2) ist es möglich, Teile des Programmes nicht im Code
direkt zu erzeugen, sondern quasi auf "Fertigprodukte" zuzugreifen, vorgefertigte Elemente,
die beim Erstellen des Programmes zum Programmcode dazugebunden (gelinkt) werden
oder gar in einer zum Programm gehörenden DLL aufgehoben werden. Eine DLL (=
Dynamische Bibliothek) kann also neben Funktionen und Prozeduren auch Resourcen
beherbergen. Die Resourcen, auf die PROFAN² zugreifen kann, sind Icons, Cursor, Bitmaps,
Strings (bis 255 Zeichen Länge), Menüs und Dialoge. So könnte man sich nun also
vorstellen, daß ein international zu vertreibendes Programm alle Strings, Dialoge und Menüs
in einer DLL enthält. Der englische Kunde erhält zu dem Programm die DLL mit den
englischen Resourcen und seine italienische Kollegin die DLL mit den italienischen
Resourcen. Die EXE-Datei des Programmes existiert nur in einer Version!
Wie kommen nun die Resourcen in die DLL oder EXE-Datei?
Hierzu benötigt man Hilfsmittel. Sehr empfehlenswert ist her der "Resource Workshop" von
BORLAND, der nicht nur bei diversen Compilern dieses Herstellers mit dabei ist, sondern
auch über BORLAND einzeln zu beziehen ist. Die zur Zeit aktuelle Version 4.5 unterstützt
Resourcen für 16 und 32 Bit. Mit diesem Programm können Resourcen optimal erzeugt und
verwaltet werden. Sollte man auf die - sicherlich nicht dumme - Idee kommen,
PROFRUN.EXE um Resourcen zu erweitern, so ist darauf zu achten, daß dies VOR dem
Linken einer PRC-Datei zur EXE-Datei geschehen muß! Wer nur 16-Bit Programme schreibt,
findet einen älteren "Resource Workshop" auch auf mancher CD, die eine ältere Version
einer BORLAND Programmiersprache enthält. (ACHTUNG: Turbo Pascal für Windows 1.0
enthielt noch ein anderes Tool, das nicht sonderlich kompatibel ist. Da war erst ab Version
1.5 der Resource-Workshop dabei.) Die Bedienung und Anwendung des "Resource
Workshop" ist in dem dazugehörigen Handuch bzw. der Online-Hilfe ausführlich erläutert, so
daß ich darauf nicht eingehe. Wer Resourcen unter PROFAN² verwenden will sollte, sich ein
solches Tool aber zulegen, damit die Möglichkeiten voll genutzt werden können. PROFAN²
enthält im Beispielverzeichnis eine DLL, die keinen Code, sondern nur Resourcen enthält. In
der 16-Bit-Version ist es die LEER16.DLL und in der Version für Windows 95 die
LEER32.DLL. Diese kann genutzt werden, um eigene Resourcen-DLLs zu erzeugen.
Wie greift man auf die Resourcen zu?
Um auf eine Resource zuzugreifen, benötigt man das Instanz- Handle der EXE-Datei bzw.
der DLL, die die Resource enthält. Im Falle einer EXE-Datei ist dies das Ergebnis der
Funktion @WinExec, bei einer DLL das Ergebnis der Funktion @UseDLL. Auf die Resourcen
einer EXE-Datei kann nur solange zugegriffen werden, solange sie läuft. Auf Resourcen im
laufenden PROFAN²-Programm kann über dessen Instanz-handle zugegriffen werden, das
sich in der Systemvariablen %HInstance findet.
WICHTIG:
Aus einem 32-Bit Programm kann man normalerweise nur auf 32-Bit-DLLs zugreifen und
umgekehrt aus einem 16-Bit-Programm nur auf 16-Bit-DLLs! PROFAN² ermöglicht jedoch
auch die Nutzung von Resourcen in 16-Bit-DLLs in einem 32-Bit-Programm. @UseDLL
wurde entsprechend erweitert: Ist der normale Aufruf (32-Bit) ungültig, wird automatisch
versucht diese DLL als 16-Bit-DLL zu öffnen. Da hierzu undokumentierte Funktionen von
Windows 95 genutzt werden, funktioniert dies aber nicht mit der auch zu Windows NT
kompatoblen Version von PROFAN².
Seite 48
RGH-PROFAN²
12.2 Icons aus Resourcen
Der Befehl DrawExtIcon ist schon seit PROFAN² 3.3 bekannt. Mit ihm können Icons aus
anderen EXE-Dateien und DLLs auf den Bildschirm gebracht werden. Allerdings bietet
Windows eine Möglichkeit, Icons aus anderen Dateien auch anzuzeigen, wenn diese nicht
mit @UseDLL oder @WinExec aktiviert sind: DrawLibIcon. Dieser Befehl ist in jedem Fall
vorzuziehen.
12.3 Cursor aus Resourcen
Mit UseExtCursor kann nun auch ein Cursor (Mauszeiger), der in den Resourcen vorhanden
ist, genutzt werden. Ein Cursor besteht aus drei "Farben": schwarz, weiß und durchsichtig.
An den durchsichtigen Stellen scheint der Hintergrund durch. Außerdem dürfen Sie nicht
vergessen, beim Erzeugen des neuen Cursors den "HotSpot" festzulegen, den Punkt zu
bestimmen, der beim Mausklick als Koordinaten weitergegeben wird. Beim Pfeil ist das die
Spitze, bei einer Hand sollte das der Zeigefinger sein.
12.4 - Bitmaps aus Resourcen
Besonders für Spiele und Multimediaanwendungen interessant ist die Möglichkeit, auch
Bitmaps in der EXE-Datei bzw. einer DLL "verstecken" zu können. Da die EXE-Datei bzw.
DLL sich beim Zugriff im Speicher befindet, sind die entsprechenden Befehle natürlich
deutlich schneller, als das Laden eines Bildes von der Festplatte. Die Befehle sind aber
nahezu die Gleichen: DrawExtBmp und DrawSizedExtBmp. Es können problemlos mehrere
Bitmaps in einer EXE-Datei bzw. DLL vorhanden sein. Was in PROFAN² (noch) nicht
möglich ist, ist das Kopieren eines Ausschnittes einer Resourcen-Bitmap auf den Bildschirm.
Es wird immer die ganze Bitmap gezeichnet. (Wenn man derartiges braucht, bleibt immer
noch der Weg über eine Bitmap als Datei, die mit MLoadBmp in den Speicher geladen und
mit MCopyBmp / MCopySizedBmp stückchenweise oder komplett auf den Bildschirm kopiert
werden kann).
Seite 49
RGH-PROFAN²
12.5 - Strings aus Resourcen
Während alle anderen Resorcen über Namen gekennzeichnet werden, bekommen die
Strings in den Resourcen eindeutige Nummern (Integer). Beim Anlegen der Resourcen ist zu
berücksichtigen, daß PROFAN² - auch in der 32-Bit-Version - nur mit Strings bis zu einer
Länge von 255 Zeichen umgehen kann. Normalerweise sollten in Programmen selbst keine
Literale (Strings in Anführungszeichen) vorkommen, wenn man daran denkt auf den
internationalen Markt zu gehen. Bei einer Anpassung sind dann nämlich nur die Resourcen
zu ändern, bzw. die Resourcen DLLs auszutauschen. (Auf diese Weise kann man sich
mittels des "Resource Workshop" auch manches internationale Programm, z.B. aus der
Shareware, für den privaten Einsatz eindeutschen. Gelesen werden Strings in den
Resourcen mittels der Funktion @ExtString$.
ACHTUNG: Eine Weitergabe derartig manipulierter Programme widerspricht in der Regel
den Copyright-Bestimmungen, nach denen Sharewareprogramme nur unverändert
weiterverbreitet werden dürfen.)
12.6 - Menüs aus Resourcen
Auch komplette Menüs können mit dem "Resource Workshop" (oder einem anderen
Resourcen-Editor) erzeugt werden. Mit UseExtMenu wird auf eine Menü aus den Resourcen
zugegriffen. Ein bereits vorhandenes Menü wird durch das neue Menü ersetzt. Es ist somit
durchaus möglich, während des Programmlaufes das Menü gegen ein anderes
auszuwechseln. So ist es denkbar, daß der Benutzer eines Programmes eine Sprache
wählen kann und dann das entrsprechende Menü geladen wird. Ebenso ist es möglich, durch
Auswechseln der Resourcen DLL die Sprache zu wechseln. Beim Erstellen mit dem
Resourcen-Editor bekommt das Menü einen Namen. Dieser wird bei UseExtMenu mit
angegeben. Jeder Menüpunkt erhält eine Befehlsnummer (ID-Wert). Diese entspricht der
Befehlsnummer bei im Programm erstellten Menüs und wird nach dem WaitInput genauso
mit @MenuItem bzw. %MenuItem abgefragt.. Hier sind Werte von 1 bis 32766 erlaubt, wobei
255 nicht verwandt werden sollte, da diese in PROFAN² eine eigene Bedeutung haben...
12.7 - Dialoge aus Resourcen
Zu den interessantesten Möglichkeiten bei der Verwendung von Resourcen zählen sicherlich
die Dialoge. Hier sind dann auch die Dialogstile möglich, die unter PROFAN² normalerweise
nicht unterstützt werden. Die Eigenschaft "Untergeordnet" (bzw. "Childwindow") sorgt zum
Beispiel dafür, daß ein Dialog das Hauptfenster nicht verlassen kann. Außerdem ist es
möglich, die Dialogelemenbte vor dem Überzeichnen zu schützen ("Schutz ..." im "Resource
Workshop" bei den Dialogeigenschaften ankreuzen.). Hier lohnt es sich gewiß, etwas zu
experimentieren und auszuprobieren.
Bei den Dialogelementen, wie Listboxen, Scrollbars, etc. geben Sie jeweils einen "ID-Wert"
and. Diese Identifikationsnummer eines Dialogelementes müssen Sie im Programm kennen,
um auf das Element zuzugreifen. Auf den Dialog greifen Sie mit @CreateExtDialog über den
Namen des Dialogs zu. Der Rückgabewert ist wie auch bei @CreateDialog das Handle des
Dialogs. Um jetzt wie gewohnt in einer WaitInput-Schleife auf die Ereignisse des Dialoges
reagieren zu können, benötigen Sie noch die Handle der einzelnen Dialogelemente. Da diese
Handle erste bei der Darstellung des Dialoges vergeben werden, benötigen Sie die Funktion
@GetHandle die zur jeweiligen Identifikationsnummer eines Dialogelementes das
entsprechende Handle zurückggibt. Der Rückgabewert ist vergleichbar mit dem Handle, daß
Sie bei im Programm erzeugten Dialogen von den @Create...-Funktionen zurückbekommen.
Die übrige Behandlung des Dialoges unterscheidet sich nicht von der eines mit
@CreateDialog erzeugten Dialoges: Anstelle des @CreateDialog steht @CreateExtDialog
und anstelle der weiteren @Create...-Funktionen zur Erzeugung der Dialogelemente steht
nun jeweils das entsprechende @GetHandle.
Seite 50
RGH-PROFAN²
Ein kleines Beispiel, das auf einen Dialog in einer "DIALOGE.DLL" zugreift, der "MELDUNG"
heißt und die Buttons "OK" mit dem ID-Wert 1 und "Abbruch" mit dem ID-Wert 2 verwendet:
Declare iDLL%, Ok%, Dlg%, Abbruch%, Ende%
CLS
Let iDLL% = @UseDLL("DIALOGE.DLL")
Let Dlg% = @CreateExtDialog(iDLL%,%HWnd,"MELDUNG")
Let Ok% = @GetHandle(Dlg%,1)
Let Abbruch% = @GetHandle(Dlg%,2)
Let Ende% = 0
WHILENOT Ende%
WaitInput
IF @GetFocus(Ok%)
Print "OK"
Let Ende% = 1
ELSEIF @GetFocus(Abbruch%)
Print "ABBRUCH"
Let Ende% = 1
ENDIF
ENDWHILE
END
Seite 51
RGH-PROFAN²
13 - Programm-Aufbau
Alle Variablen in PROFAN müssen vorher (wie etwa in PASCAL) deklariert werden. Die
DECLARE- und DIM-Befehle sollten am Anfang des Programmes stehen. Lokale Variablen
sollten am Anfang einer Prozedur definiert werden. Vor der ersten Bildschirmausgabe sollte
immer ein WINDOW (oder CLS) stehen, um das Bildschirmfenster zu öffnen. Hierbei ist der
Befehl WINDOW vorzuziehen. Der eigentliche Sinn von CLS liegt darin, ein bestehendes
Fenster zu bereinigen, wobei dazu auch eine Farbe angegeben werden kann.
BEISPIEL:
'DEKLARATIONSTEIL
'---------------DECLARE ...
DIM% ...
DIM$ ...
'INCLUDE-DATEIEN MIT FUNKTIONEN UND PROZEDUREN
'--------------------------------------------$I TOOLBOX.INC
'DEFINITION VON FUNKTIONEN
'------------------------DEF @...
'PROZEDUREN
'---------PROC ...
PARAMETERS ...
DECLARE ...
...
ENDPROC
'DAS HAUPTPROGRAMM
'----------------WINDOWTITLE ...
WINDOWTYPE ...
WINDOW ...
...
...
...
END
Sicher sind auch Programme ohne Fenster (d.h. ohne Bildschirmausgabe) möglich oder
Programme, die nur ein (oder mehrere) Dialogfenster haben.
Seite 52
RGH-PROFAN²
14 - Befehle über mehrere Zeilen
Der Übersichtlichkeit wegen können Befehle (Programmzeilen) auch über mehrere
Bildschirmzeilen geschrieben werden. Ist das letzte Zeichen einer Zeile ein \ , so wird die
nächste Zeile ab dem ersten Zeichen, das kein Leerzeichen ist, angehängt. Beispiele:
MESSAGEBOX "Überschrift",\
"Das ist ein Testtext, der \
etwas länger ist!",16
PRINT "Das ist ein ziemlich lang\
er Text!"
COPYSIZEDBMP 34,34-16-16 > \
12,12-32,32 ; 0
Beachten Sie: Auch eine Programmzeile über mehrere Bildschirmzeilen darf nicht länger als
254 Buchstaben sein. Führende und folgende Leerzeichen werden nicht gezählt.
Seite 53
RGH-PROFAN²
15 - Fehlerbehandlung - Trace-Modus
Fehlermeldungen und Warnungen werden in deutsch in einer Messagebox auf den
Bildschirm gebracht. Nach einer Fehlermeldung bricht das Programm ab, nach einer
Warnung läuft es weiter, wenn Sie "OK" anklicken oder bricht ab, wenn Sie "Abbrechen"
wählen. Neben der Fehlerbeschreibung wird beim Interpreter auch die fehlerhafte Zeile
angegeben, sodaß der Fehler genau lokalisiert werden kann. Die Systemvariable
%ErrNumber enthält die Fehlernummer. Beim Auslesen wird sie auf Null zurückgesetzt. Eine
Liste aller Fehlermeldungen befindet sich im Anhang.
Zusätzlich wird (auch wenn der Fehler im compilierten Programm auftritt) die Zeilennummer
angegeben. Da aber Includedateien mitgezählt werden und andererseits mit dem Backslash
"\" verbundene Zeilen als eine gezählt werden, kann diese Zahl nur als Anhaltspunkt dienen.
Auf alle Fälle ist es sehr dringend anzuraten, jegliches Programm im Interpretermodus auf
Herz und Nieren zu testen, bevor man es compilert startet.
Das Fehlerverhalten kann über den Befehl SETERRORLEVEL gesteuert werden. Der Befehl
hat folgende mögliche Parameter:
210-1 -
Für ganz Vorsichtige: Warnungen werden wie Fehler behandelt und führen zu
einer Fehlermeldung mit Programmabbruch.
Für die Programmentwicklung: Auch Warnungen werden ausgeben, aber das
Programm läuft auf Wunsch weiter.
Der Normalzustand: Warnungen werden nicht angezeigt. Diesen Errorlevel sollte
man bei einem fertigen Programm verwenden.
Fast schon kriminell: Auch Fehlermeldungen werden übergangen.Das kann unter
Umständen zu einem Windowsfehler oder Absturz des Systemes mit Datenverlust
führen.
Warnungen treten auf, wenn ein Ausdruck nicht als numerischer Wert zu interpretieren ist
oder z.B. eine Bilddatei nicht gefunden wird oder BITMAP-Befehle wegen
Speicherplatzmangels nicht ausgeführt werden ... also immer dann, wenn keine
ernstzunehmenden Folgen für das restliche Programm zu erwarten sind.
Unabhängig vom gesetzten Errorlevel wird die Systemvariable %ERROR bei einer Warnung
bzw. einem Fehler gesetzt. Auf diese Weise kann also der Programmierer die komplette
Verantwortung zu Behandlung von Fehlern übernehmen. Wie auch %IORESULT wird
%ERROR beim ersten Auslesen wieder auf 0 gesetzt. Die möglichen Error-Werte:
012-
seit dem letzten Lesen von %ERROR ist kein Fehler aufgetreten
eine Warnung wird gemeldet
ein Fehler wird gemeldet
ACHTUNG: Bei Dateioperationen wird nicht %ERROR verwandt, sondern die
Systemvariable %IORESULT gesetzt, das Programm aber in keinem Fall abgebrochen. Das
Programm muß also diese Variable auswerten, da ansonsten Abstürze möglich sind.
Seite 54
RGH-PROFAN²
Nach einer Dateioperation oder einer Directory-Suche enthält diese Variable den
entsprechenden Wert:
023512 15 16 17 18 100 101 102 103 104 105 106 -
kein Fehler aufgetreten
Datei nicht gefunden
Pfad nicht gefunden
Zugriff verweigert (ReadOnly?)
Ungültiger Dateimodus
Laufwerksnummer unzuzulässig
Verzeichnis kann nicht gelöscht werden (noch Dateien drin?)
RENAME nicht über Laufwerksgrenzen möglich (siehe Rename)
Kein weiterer Eintrag (bei @FindFirst/@FindNext)
Lesefehler von Diskette/Platte
Schreibfehler auf Diskette/Platte
Dateinummer ist keiner Datei mit ASSIGN zugeordnet (siehe Assign)
Datei nicht offen (Reset, Rewrite oder Append fehlt)
Datei nicht zum Lesen geöffnet (Reset fehlt)
Datei nicht zum Schreiben geöffnet (Rewrite oder Append fehlt)
Falsches Format (bei Input #N,..)
Eine dritte Art Fehler kann bei der Ansteuerung von Multimediageräten über die MCISchnittstelle erfolgen. Der zuletzt gemeldete Fehler beim Senden eines MCI- Strings zur
Ansteuerung eines Multi-Media-Treibers (etwa CD, Soundkarte, MIDI- Gerät, etc.) wird in der
Systemvariable %MCIERROR festgehalten. Wie auch %ERROR und %IORESULT wird sie
beim ersten Auslesen auf 0 zurückgesetzt. Die Bedeutung der Fehlernummern hängt vom
MCI-Gerätetreiber ab und ist für sich daher wenig aussagekräftig. Für den Programmierer
bedeutet ein Wert ungleich Null lediglich, daß ein Fehler aufgetreten ist und die Funktion
@MCISEND$ nicht einen Ergebnisstring zurückliefert, sondern eine Fehlermeldung (in der
Landessprache).
Um ein Programm im Interpreter zu testen, kann der Trace-Modus mit TraceOn
eingeschaltet werden. Während das Programm im Tracemodus läuft, wird jede
Programmzeile vor Ihrer Ausführung in einer Messagebox angezeigt. Der Befel TraceOff
schaltet den Trace-Modus wieder aus. Das compilierte Programm ignoriert die Befehle
TraceOn und TraceOff.
Seite 55
RGH-PROFAN²
16 - Text- und Grafikmodus
PROFAN kennt (für Windows unüblich) einen Text- und einen Grafikmodus. Da Windows
natürlich nur einen Grafikbildschirm hat, wird der Textmodus auf diesem simuliert.
Der Grafikmodus ist der windowseigene Modus, der nahezu all die Möglichkeiten bietet, die
das Windows-Grafik-Interface beeinhaltet.
Der Textmodus simuliert im Hauptfenster einen DOS-Bildschirm, der zeichenorientiert ist.
Es gibt keinen SCREEN-Befehl, um zwischen den Modi umzuschalten, da immer beide
gleichzeitig verfügbar sind.
16.1 Der "Textmodus"
Im Textmodus funktionieren die von BASIC her bekannten Befehle, wie z.B. PRINT,
LOCATE, INPUT, COLOR und CLS in gewohnter Weise. Zusätzlich sind in diesem Modus
Befehle wie TBOX, FONT und @TMOUSE verfügbar. Ein wesentlicher Unterschied ist, daß
CLS ohne Parameter den Bildschirm nicht in der aktuellen Farbe löscht, sondern
grundsätzlich in weiß. Bei INPUT ist kein Prompt-Text erlaubt, sondern nur die Angabe einer
Variable. Ein kleines Beispiel:
Declare Zahl%, Text$
WindowTitle "Testprogramm"
Cls
Locate 2,2
Print "Das ist die Überschrift"
Font 2
Locate 4,2
Print "Bitte gebe einen Text ein: ";
Input Text$
Print "Bitte gebe eine Zahl ein: ";
Input Zahl%
Font 0
Print
Color 1,15
Print "Du hast eingeben:",Zahl%,Text$
WaitKey
End
Das Semikolon nach einem Ausdruck beim Print-Befehl sorgt dafür, daß die nächste
Ausgabe in die gleiche Zeile geht und direkt an die vorherige anschließt. Bei einem Komma
wird hingegen ein Leerzeichen gelassen. (Die von BASIC her bekannte Tabulatorfunktion
gibt es nicht.) Der Befehl WAITKEY wartet auf einen Tastendruck. Möchte man wissen,
welche Taste gedrückt wurde, kann man die Systemvariable %KEY abfragen. Ebenso hätte
man den Befehl WAITINPUT nutzen können, dann werden zusätzlich die Maustasten
abgefragt. Das Ergebnis findet sich in der Systemvariablen %MOUSEKEY, wobei 1 für die
linke und 2 für die rechte Maustaste steht. (In diesem Zusammenhang sei auch auf die
Befehle WAITSCAN und WAITMOUSE, sowie die Funktionen @KEYIN, @INKEY$ und
@GETKEY$ hingewiesen.)
Mit dem Befehl FONT kann der Bildschirmfont im Textmodus eingestellt werden (0 =
System, 1 = OEM (ASCII), 2 = ANSI). COLOR stellt die Textfarbe ein, wobei wie in BASIC
Farbwerte von 0 bis 15 erlaubt sind.
Oftmals möchte man Zahlen und Texte formatiert ausdrucken. Dies ist in PROFAN² mittels
der Befehle NUMWIDTH, STRWIDTH und DECIMALS möglich. Mit DECIMALS wird
festgelegt, wieviele Dezimalstellen bei der Ausgabe mit PRINT (und auch bei der
Umformung mit @STR$) berücksichtigt werden:
Seite 56
RGH-PROFAN²
Declare Kreiszahl!
Let Kreiszahl! = @PI()
Decimals 0
Print Kreiszahl!
Decimals 5
Print Kreiszahl!
Decimals 10
Print Kreiszahl!
WaitKey
End
Voreingestellt ist ein Wert von 6, d.h. wenn nichts anderes angegeben wird, werden 6 Ziffern
hinter dem Komma ausgegeben. Mit NUMWIDTH kann ich festlegen, wieviele Zeichen
mindestens gedruckt werden. Ist die Zahl kürzer, wird sie mit führenden Leerzeichen
ausgegeben. Das ermöglicht die Ausgabe von Tabellen:
Decimals 3
Numwidth 2
Print @PI()
Numwidth 6
Print @PI()
Numwidth 8
Print @PI()
WaitKey
End
Gleiches ist mit STRWIDTH für die Ausgabe von Strings möglich. Beide Werte sind mit 0
vorbelegt, sodaß normalerweise alle Zahlen und Texte ohne führende Leerzeichen
ausgegeben werden.
Auch im Textmodus kann mit (wenn auch simulierten) "Buttons" gearbeitet werden, wobei
abgefragt werden kann, ob ein Maus-Klick in diesem Button erfolgte. Ein kleines
Beispielprogramm:
Seite 57
RGH-PROFAN²
Declare Ende%
Cls
' Der Button
Color 15,2
TBox 10,10 Locate 13,13
Print "A"
' Der Button
Color 15,3
TBox 10,20 Locate 13,23
Print "B"
Color 15,0
"A" wird gezeichnet
15,15; 3
"B" wird gezeichnet
15,25; 0
Let Ende% = 0
WhileNot Ende%
'Solange Ende den Wert 0 hat ...
WaitInput
'Auf Tastendruck oder Mausklick warten
If @TMouse(10,10 - 15,15) 'Mausklick im Button A?
Locate 20,0
Print "Du hast 'A' gedrückt!"
Let Ende% = 1
ElseIf @TMouse(10,20 - 15,25) 'Mausklick in B?
Locate 20,0
Print "Du hast 'B'' gedrückt!"
Let Ende% = 1
ElseIf @KeyIn("Aa") 'Taste "A"?
Locate 20,0
Print "Du hast 'A' gedrückt!"
Let Ende% = 1
ElseIf @KeyIn("Bb") 'Taste "B"?
Locate 20,0
Print "Du hast 'B'' gedrückt!"
Let Ende% = 1
Else 'Nichts von alledem ...
Locate 20,0
Print "Daneben ..."
EndIf
Wend
WaitKey
End
Der Befehl TBOX zeichnet in der mit COLOR eingestellten Farbe ein Rechteck zwischen den
angegebenen Koordinatenpaaren. Wie auch bei LOCATE ist die jeweils erste Koordinate die
Zeile und die zweite die Spalte. Der fünfte Parameter gibt die Art des Rahmens an: 0 einfacher Rahmen; 1 - doppelter Rahmen; 2 - teils einfach, teils doppelt; 3 - kein Rahmen.
Der Rahmen wird mit ASCII- Grafikzeichen gemalt. Die Funktion @TMOUSE hat dann den
Wert 1, wenn der letzte Mausklick in dem durch die zwei Koordinatenpaare angegebenen
Rechteck erfolgte. Die Funktion @KEYIN hat den Wert 1, wenn die zuletzt gedrückte Taste
im Funktionsargument (ein String) enthalten ist. Das Beispielprogramm demonstriert, wie
man Programme schreibt, die sowohl auf die Maus als auch auf die Tastatur reagieren.
Seite 58
RGH-PROFAN²
16.2 Der "Grafikmodus"
Hier kommen die windowseigenen Text- und Grafikbefehle zur Geltung. Der fortgeschrittene
Programmierer wird diesen Befehlen den Vorzug vor den textorientierten Befehlen geben.
Alle Koordinatenangaben erfolgen hier in Pixel, also im Bereich 0,0 (links oben) bis z.B. bei
Standard-VGA und Vollbildmodus 639,479 (rechts unten). Die maximal mögliche Größe des
Bildschirmes erfahren wir über die Systemvariablen %MaxX und %MaxY. Übrigens: Die
mögliche Farbtiefe liefert uns die Systemvariable %BitsPixel.
Wenn man mit WINDOW eine andere Größe eingestellt hat, ist der Bereich natürlich
entsprechend kleiner bzw. größer. Die augenblickliche Fensterposition und -größe läßt sich
mit den Systemvariablen %WINTOP, %WINBOTTOM, %WINLEFT und %WINRIGHT
ermitteln, wobei diese die Koordinaten in Bezug zur linken oberen Bildschirmecke angeben.
Um z.B. die tatsächliche Breite des Fensters zu ermitten, ist ein wenig Rechnen angesagt:
Let WinWidth% = %WinRight - %WinLeft
Während diese Systemvariablen die Außenmaße des Hauptfensters betreffen, kann man mit
@Height und @Width die Innenmaße eines beliebigen Fensers, also auch von
Dialogfenstern und Dialogboxen, ermitteln.
WICHTIG: Vor jedem der Ausgabe-Befehle (dazu gehören auch alle USE-Befehle) muß
entweder Programmfenster geöfnet sein, oder die Grafikausgabe mit StartPaint auf ein
anderes Fenster umgeleitet sein. Zum Öffnen des Programmfensters (Hauptfenster eines
Programmes) verwenden wir den Befehl CLS oder WINDOW. Mit den Befehlen
WINDOWSTYLE und WINDOWTITLE können wir zuvor die Attribute unseres Fensters
festlegen!
Zunächst einmal wollen wir Schrift auf den Bildschirm bringen. Dazu legen wir die Textfarbe
mit dem Befehl TEXTCOLOR fest. Der erste Parameter ist die Vordergrundfarbe und der
zweite die Hintergrundfarbe. Beide Werte sind Farbwerte im Bereich von 0 bis 32767 bzw.
16 Millionen, je nach eingestelltem Farbmodus. Der Modus wird mit SetTrueColor eingestellt.
Im Modus 0, der standardmäßig voreingestellt ist, gibt es 32768 Farben, in Modus 1 sind es
16 Millionen mögliche Farbwerte. (Wenn der in Windows eingestellte Grafikmodus weniger
Farben erlaubt, wird die nächstliegende Farbe angezeigt.)
Da man sich unmöglich merken kann, welche Farbe welchen Wert hat, gibt es die Funktion
@RGB. Diese hat drei Parameter, die für den ROT-, GRÜN- und BLAU-Anteil der Farbe
stehen. Sind alle drei Parameter auf 0, ist die Farbe schwarz, sind alle auf 31 (in Farbmodus
0) bzw. 255 (in Farbmodus 1) gibt es ein reines Weiß.
Eine Besonderheit gilt noch für die Hintergrundfarbe: Ist diese -1, so bedeutet das einen
transparenten Hintergrund; d.h. der Hintergrund wird zwischen den Buchstaben sichtbar. Als
nächstes müssen wir die Schriftart, den Font festlegen. Unter PROFAN² können wir alle
Windows-Fonts einschließlich der True-Type-Fonts anwenden. Zur Einstellung eines Fonts
dient der USEFONT- Befehl, der eine Reihe von Parametern hat: Der erste Parameter ist der
Name des Fonts, z.B. "ARIAL" oder "COURIER NEW", wie er auch in der Font-Auswahl
anderer Programme erscheint. Der zweite und der dritte Parameter geben Zeichenhöhe und
-breite in Punkt an. Wird 0 angegeben, wird ein Defaultwert benutzt. der 4. bis 6. Parameter
sind Schalter, die angeben, ob der Font unterstrichen, kursiv und/oder fett ausgegeben
werden soll. Die Parameter im Überblick:
1. S : String - Fontname
2. N1 : Integer - Zeichenhöhe
3. N2 : Integer - Zeichenbreite
4. N3 : Integer - Fett? (0 .. 1)
5. N4 : Integer - Kursiv? (0 .. 1)
6. N5 : Integer - Unterstrichen? (0 .. 1)
Seite 59
RGH-PROFAN²
Für TrueType-Fonts ist noch der Befehl ORIENTATION interessant. Hier kann in 10tel Grad
eingestellt werden, in welche Richtung der Text ausgegeben wird. Der ORIENTATION-Befehl
muß vor (!) dem USEFONT-Befehl kommen, damit er wirkungsvoll wird. Außerdem gibt es
noch den CHARSET-Befehl, der dem USEFONT-Befehl mitteilt, welcher Zeichensatz zu
wählen ist, wenn der verlangte Font nicht vorhanden ist. In diesem Fall sucht Windows
nämlich einen möglichst ähnlichen Font aus ... und der sollte den gleichen Zeichensatz
haben. Angezeigt wird der Text schließlich mit dem DRAWTEXT-Befehl, dessen erste
beiden Parameter die Koordinaten sind. Ein kleines Beispiel:
Cls
TextColor @RGB(31,0,0),-1
CharSet 0
Orientation 300 ' 30°-Winkel
UseFont "ARIAL",30,40,1,0,1
DrawText 30,300,"Dies ist ein Text"
WaitKey
Ab Version 2.5 von PROFAN² kann auch eine numerische Variable bzw. Systemvarible mit
DRAWTEXT ausgegeben werden, wobei zur Formatierung die Einstellungen mit
NUMWIDTH und DECIMALS herangezogen werden.
Selbstverständlich können wir mit PROFAN² auch Punkte und Linien zeichnen. Einen Punkt
setzen wir mit dem SETPIXEL-Befehl. Als Parameter übergeben wir die Koordinaten und die
Farbe:
SetPixel 123,200,@RGB(13,20,3)
Wenn Ihr Gafiktreiber nicht alle in PROFAN² möglchen 32768 bzw. 16 Millionen Farben
unterstützt, wird der Punkt in der nächstmöglichen Farbe gesetzt. Ausgelesen werden kann
ein Bildpunkt mit der Funktion @GETPIXEL, die den tatsächlichen Farbwert eines Punktes
ermittelt:
LET A% = @GetPixel(123,200)
Mit den Funktionen @GETRVALUE, @GETGVALUE bzw. @GETBVALUE lassen sich die
einzelnen Farbkomponenten ermitteln.
Vor dem Linienziehen müssen wir festlegen, welchen Stift wir verwenden. Das erledigt der
Befehl USEPEN. Der erste Parameter ist die Linienart, der zweite die Linienstärke und der
dritte die Farbe. Die Linienarten 1 bis 5 (gestrichelt und gepunktet) sind nur bei Linienstärke
1 sinnvoll, d.h. dickere Linien werden immer durchgezogen dargestellt. Der eingestellte Stift
gilt für alle (!) folgenden Grafikbefehle, mit Ausnahme von SETPIXEL. Eine Linie ziehen wir
mit dem Befehl LINE, gefolgt von zwei Koordinatenpaaren. Zusätzlich gibt es noch den
Befehl MOVETO, mit dem der Grafik-Kursor versetzt wird, ohne eine Linie zu zeichnen und
den Befehl LINETO, der eine Linie vom Grafik-Kursor zum angegebenen Punkt zeichnet.
Probieren Sie folgendes Beispiel aus:
Cls
UsePen 2,1,@RGB(0,31,0)
Line 20,20 - 100,100
LineTo 100,20
MoveTo 120,20
LineTo 120,60
WaitInput
Seite 60
RGH-PROFAN²
Zusätzlich gibt es noch Befehle, um Flächen-Objekte (Rechtecke, Kreise, etc.) zu zeichnen.
All diesen ist gemeinsam, daß die ersten beiden Koordinatenpaare das Rechteck
angebeben, in dem das Objekt Platz findet. Außerdem muß der Pinsel definiert werden, mit
dem das Objekt ausgemalt wird. Diese geschieht mit dem Befehl USEBRUSH. Dabei ist der
erste Parameter die Art des Pinsels und der zweite die Farbe. Als Art des Pinsels kommen 0
(transparent = nicht ausgefüllt), 1 (voll ausgefüllt) und 2 - 8 (verschiedene Schraffuren) in
Betracht. Die Umrandung des Objektes wird durch den Stift mit USEPEN bestimmt. Soll kein
Rand gezeichnet werden, muß ein Stift mit Linienstärke 0 definiert werden. Folgende Befehle
für Grafikobjekte gibt es: RECTANGLE (Rechteck), ROUNDRECT (mit abgerundeten
Ecken), ELLIPSE (auch für Kreise), CHORD (Kreisabschnitt), ARC (Kreisbogen) und PIE
(Kreisausschnitt: "Tortenstück"). Ein kleines Beispiel, um ein rotes Rechteck mit blauem
Rand zu zeichnen, dazu ein ebensolcher Kreis:
Cls
UsePen 1,4,@RGB(0,0,31)
UseBrush 1,@RGB(31,0,0)
Rectangle 30,30 - 200,200
Ellipse 100,100 - 300,300
WaitInput
Der Befehl ROUNDRECT erwartet noch ein Parameterpaar zu Definition der Abrundung und
die Befehle ARC, CHORD und PIE erwarten jeweils noch ein Koordinatenpaar für den
Beginn und eines für das Ende des betreffenden Ab- bzw. Ausschnittes. Näheres dazu finden
Sie in der Referenz. Machen Sie ruhig ein paar Experimente und Sie finden sich schnell in
der Windowsgrafik zurecht! Es sei an dieser Stelle auch noch auf den Befehl FILL
hingewiesen, mit dem beliebige umrandete Flächen ausgefüllt werden können.
Ab Version 6.0 ist auch ein "virtuelles" Koordinatensystem möglich. Das Koordinatensystem
des Hauptfensters bzw. des mit STARTPAINT aktivierten Fensters wird mit dem SCRRENBefehl auf beliebige Breite und beliebige Höhe festgelegt. Alle weiteren Koordinatenangaben
beziehen sich auf das mit SCREEN eingestellte Koordinatensystem. Auch die Anzeige von
Bitmaps bezieht sich nun auf dieses neue Koordinatensystem. Auf diese Weise sind
Bildschirmausgaben möglich, die sich immer an die aktuelle Fenstergröße anpassen.
Beispiel:
Cls
ShowMax
' Fenster auf Maximalgröße vergrößern
Screen 3000,2000
Rectangle 100,100 - 2900,1900
WaitInput
Unabhängig vom eingestellten Bildschirmmodus bedeckt das Rechteck nahezu den ganzen
Bildschirm.
Seite 61
RGH-PROFAN²
17 - Bitmaps
Wichtig unter Windows sind natürlich die Bilddateien. PROFAN² unterstützt hier das
windowseigene Bitmap-Format, gekennzeichnet durch die Endung BMP! Die WindowsHintergrundbilder sind in diesem Format abgelegt und nahezu jedes Grafikprogramm unter
Windows versteht dieses Format, so auch das mit Windows mitgelieferte Programm
Paintbrush. Außerdem wird auch das sehr verwandte komprimierte RLE-Format unterstützt.
Viele auf dem Markt befindliche Grafik-Konverter für Windows, wie z.B. das sehr
empfehlenswerte PAINTSHOP PRO, daß es sowohl für Windows 3.x als auch Windows 95
gibt, können Bilder in dieses platzsparende Format umwandeln.
Mit dem Befehl LOADBMP wird eine Grafik geladen und in Originalgröße angezeigt. Wir
müssen also den Namen des Bildes wissen und wohin auf dem Bildschirm es ausgegeben
werden soll. Beispiel:
LoadBmp "PAPER.BMP", 10, 10; 0
Der letzte Parameter ist der Abbildungsmodus. Die 0 steht für unveränderte Abbildung.
Andere Werte bedeuten Verknüpfungen mit dem Hintergrund oder negative Darstellung (z.B.
OR, AND oder XOR-Verknüpfung):
-1 01234-
Transparenz
normales Kopieren
Quelle und Ziel mit UND verknüpft
Quelle und Ziel mit ODER verknüpft
Quelle und Ziel mit XOR verknüpft
Zielbereich invertieren (Quellbereich wird nicht berücksichtigt)
Bitmaps können auch eine transparente Farbe enthalten. Dazu gibt es den Abbildungsmodus
-1. Dieser kann ausschließlich bei den Befehlen LOADBMP, COPYBMP, MCOPYBMP,
CLIPLOADBMP und DRAWEXTBMP verwandt werden:
MCOPYBMP 10,10-100,100 > 50,50;-1
Welche Farbe als transparent angesehen wird, bestimmt das linkeste unterste Pixel einer
Bitmap. Auf diese Weise lassen sich endlich auch unter PROFAN Sprites aus Bitmaps
verwenden. Zusammen mit der Möglichkeit, Bitmaps im Speicher zu halten, sollten sich
recht ansprechende Animationen erzeugen lassen.
Da jedes Bild eine eigene Palette haben kann, wird die Palette auf das aktuelle Bild
eingestellt. Vorher geladene Bilder können dadurch falsche Farben erhalten.
Soll das Bild nicht in der Origionalgröße angezeigt werden, sondern in einer genau
festgelegten Größe, so verwenden wir den Befehl LOADSIZEDBMP, der zusätzlich noch
Parameter über Breite und Höhe des Bildes benötigt:
LoadSizedBmp "C:\WIN31\CHESS.BMP", 10,10 - 100, 80; 0
Mit dem Befehl MLOADBMP kann eine Bildatei auch in den Speicher geladen werden, ohne
daß Sie angezeigt wird. Der einzige Parameter ist dann der Dateiname. Mit MCOPYBMP
oder MCOPYSIZEDBMP kann dann ein Teil oder das ganze Bild aus dem Speicher auf den
Bildschirm kopiert werden:
MLoadBmp "SATURN.BMP"
MCopyBmp 20,20 - 200,200 > 10,10;0
Wichtige Daten über die geladene Bildatei enthalten die Systemvariablen %BmpX, %BmpY
und &BmpCol: Breite, Höhe und Anzahl der verwandten Farben.
Seite 62
RGH-PROFAN²
Neu ab Version 6.0 ist die Möglichkeit eine Bitmap im Speicher gezielt anzulegen. Hierzu
dient der Befehl MCLS, mit dem eine Speicherbitmap in der angegebenen Größe erzeugt
wird:
MCLS 1024,768
Eine zuvor mit MLOADBMP geladene Bitmap würde dadurch allerdings überschrieben
werden. Ebenso überschreibt ein MLOADBMP eine zuvor im Speicher befindliche Bitmap.
Der neue Befehl COPYBMPTOMEM kopiert einen Teil des Bildschirmes in einem beliebigen
Bereich der Speicherbitmap:
COPYBMPTOMEM 30,30-100,100 > 500,500
Um die Speicherbitmap zu beschreiben, bemalen oder mit Bildern zu füllen kann die
Graphikausgabe mit STARTPAINT umgeleitet werden, indem als Parameter statt eines
Fensterhandles die -1 angegeben wird:
MCLS 500,500
STARTPAINT -1
LOADBMP "WINLOGO.BMP",0,0;0
LINE 10,10 - 50,50
ENDPAINT
Auf diese Weise ließen sich also auch mehrere kleine Bitmaps (z.B. Sprites) in eine größere
Speicherbitmap laden. Anschließend könnten beliebige Teile wie gewohnt etwa mit
MCOPYBMP auf den sichtbaren Bildschirm gebracht werden. Während der Umleitung auf
die Speicherbitmap machen die Befehle COPYBMP, COPYBMPTOMEM und MCOPYBMP
allerdings wenig Sinn, da sie dann nur ein Kopieren innerhalb der Speicherbitmap zur Folge
hätten, da die Umleitung sowohl Quell- als auch Zielbitmap betrifft.
WICHTIG: Aus Performancegründen findet beim Beschreiben der Speicherbitmap keine
Überprüfung statt, ob diese auch groß genug ist. Wenn Sie mehr reinkopieren als reinpaßt
oder in nicht existierene Bereiche malen, kann es zum Absturz von Windows mit
Datenverlust kommen!
Ein weiterer "Speicherplatz" für Bitmaps ist die Zwischenablage. Zwei neue Befehle geben
nun auch PROFAN die Möglichkeit diese zu nutzen: Mit SAVEBMPTOCLIP wird ein Bereich
des Bildschirmes in die Zwischenablage kopiert und mit CLIPLOADBMP wird der Inhalt der
Zwischenablage - so er eine Bitmap ist - mit dem angegebenen Abbildungsmodus auf den
Bildschirm gebracht:
CLEARCLIP
SAVEBMPTOCLIP 0,0-180,180
CLIPLOADBMP 100,100;0
Dem Austausch von Bitmaps mit anderen Grafikprogrammen steht also nun nichts mehr im
Wege.
Auch Bitmaps aus den Resourcen von DLLs und Programmen können auf den Bildschirm
gebracht werden. Hierzu dienen die Befehle DRAWEXTBMP und DRAWSIZEDEXTBMP.
Es können auch beliebige Bildschirmbereiche von einem Ort zum anderen kopiert werden.
Auch hier gibt es die Möglichkeit in der Originalgröße zu kopieren oder aber die Größe zu
verändern (Lupenfunktion):
Seite 63
RGH-PROFAN²
CopyBmp 10,10 - 100,80 > 200,200; 0
CopySizedBmp 10,10 - 100,80 > 200,200 - 200,160; 0
Eine weitere Möglichkeit ist das Abspeichern eines beliebigen Bildschirmausschnittes als
Bitmap-Datei:
SaveBmp "D:\GRAFIK\TEST.BMP", 10,10 - 100,80
Desweiteren gibt es natürlich auch in PROFAN² die kleinen Symbolbilder, die Icons. Zum
einen stehen die Windows-System-Icons zur Verfügung. Diese werden über eine Nummer
angesprochen und an beliebiger Stelle angezeigt:
01234-
leeres Rechteck
STOP-Zeichen
Fragezeichen
Ausrufezeichen
Info-Zeichen
Beispiel:
DrawSysIcon 3, 10,50
Einige weitere Icons sind in PROFAN² eingebaut, um diese auszugeben, muß man deren
Namen wissen:
PROFAN KNOPF1 EIS
BAUM KNOPF2 COMPUTER
WEG TEXT GESICHT
EIMER MUELL MUENZE
STEIN WINDOWS WASSER
DOS EDITOR SAND
Beispiel:
DrawIcon "GESICHT", 30,80
Hier sei noch der Hinweis angebracht, daß ein Icon eine feste Größe von 32 * 32 Pixel hat.
Die in PROFAN² vorhandenen Icons können mit einem Resourcen-Editor und manchem
Icon-Malprogramm verändert und teilweise sogar umbenannt werden. Sie können mit diesen
Werkzeugen sogar Icons hinzufügen. WICHTIG: Bei als EXE-Datei gelinkten PROFAN²Programmen dürfen weder Icons entfernt noch hinzugefügt werden. Das Programm würde
dann nicht mehr funktionieren. Den PROFAN²-Interpreter oder das Runtime-Modul können
Sie beliebig um Icons erweitern. Eine EXE-Datei bekommt immer die Icons die das RuntimeModul zur Zeit des Linkens hat.
Es können auch Icons aus anderen Dateien (.EXE, .DLL oder .ICO) benutzt werden. Ein
direkter Zugriff auf Icons in anderen Dateien ist über DrawLibIcon gegeben. Es können Icons
in beliebigen Dateien (EXE-Dateien, DLLs und Icon-Dateien) genutzt werden. Es ist der
Name der Datei, die das Icon enthält, und die Nummer des Icons anzugeben. Die Zählung
beginnt mit Null. Beispiele:
DrawLibIcon "MOREICON.DLL",23,70,100
DrawLibIcon "TEST.ICO",0,110,100
Mit der Funktion @IconCount kann die Anzahl der Icons in einer Datei ermittelt werden.
Seite 64
RGH-PROFAN²
Ein letzter Hinweis zu den Icons: Auch das Icon, das ein PROFAN²-Programm bei
Verkleinerung zum Symbol erhält kann eingestellt werden. Hierfür dient der Befehl
USEICON:
UseIcon "GESICHT"
Seite 65
RGH-PROFAN²
18 - Sounds
Wenn auch die meisten Windowsprogrammiersprachen aus unerfindlichen Gründen keine
Befehle zur Tonerzeugung vorsehen (so. z.B. WinBasic, Visual Basic, TurboPascal für
Windows, ...), bietet PROFAN² hier einiges an:
Zunächst einmal ist das der aus BASIC bekannte BEEP-Befehl, der einen kurzen Ton
erzeugt. Mehr Möglichkeiten bietet da schon der SOUND-Befehl, dem als Parameter die
Frequenz (in Hz) und die Dauer (in 360tel Sekunden) übergeben wird:
SOUND 440,360
Diese Zeile erzeugt eine Sekunde lang den Kammerton A! Übrigens kann dieser Befehl auch
zum Erzeugen einer Pause benutzt werden, indem man als Tonhöhe 32767 angibt. Aber
aufgepaßt: In dieser Zeit wird Windows 3.1 komplett angehalten! In der 32-Bit-Version von
PROFAN² unter Windows 95 wird der Befehl wirkungslos sein, daher sollte man ihn
möglichst nicht verwenden.
Musikalisch wird es mit dem PLAY-Befehl, der als Parameter den Notenwert (in
Halbtonschritten), die Notenlänge und die Punktierung erwartet. Der Notenwert beginnt beim
tiefsten Ton mit 1. Eine Oktave höher ist dann der Ton 13. Ton 0 steht für die Pause. Die
Notendauer wird reziprok angegeben, d.h. eine Viertelnote hat die Notendauer 4, eine
Achtelnote die Notendauer 8, etc. Schließlich folgt die Anzahl der Punkte. Eine Punktierte
Achtelnote würde z.B. mit folgender Zeile gespielt:
PLAY 16,8,1
PLAY wurde für die MIDI-Wiedergabe über die Soundkarte erweitert: Werden statt eines
Notenwertes mehrere durch Semikolon getrennt angegeben, werden diese gleichzeitig über
die verschiedenen Kanäle wiedergegeben. Die Kanäle 1 bis 16 entsprechen den MIDIKanälen mit dem Unterschied, das der 4. und 10. Kanal vertauscht wurden. Das Schlagzeug
befindet sich also bei General-MIDI jetzt auf Kanal 4, was das Erzeugen dreistimmiger Songs
mit Schlagzeugbegleitung vereinfacht. Ein Dreiklang:
PLAY 16;18;20,8,1
Wenn Dauer größer als 0 ist, werden die Töne entsprechend lang gespielt und das
Programm verharrt. Ist die Dauer 0, wird der Ton angestoßen und der Ton klingt im
Hintergrund solange bis er ausgeschaltet wird. Ausgeschaltet wird ein Ton, indem mit
vorangestelltem Minus-Zeichen ausgegeben wird.
Ist die Dauer -1, wird kein Ton erzeugt, sondern die Werte N1 bis N16 als Instrumente
interpretiert, die den 16 Kanälen zugewiesen werden. Das Beispiel spielt einen C-Akkord
(25;27;29) auf der Kirchenorgel (Instrument 20) solange, bis eine Taste gedrückt wird:
PLAY 20;20;20,-1,0
PLAY 25;27;29,0,0
WAITKEY
PLAY -25;-27;-29,0,0
Noch musikalischer ist der MUSIC-Befehl. Als Parameter hat er einen String in einer eigenen
Makrosprache. Diese Makrosprache ist kompatibel zur Music-Makro-Sprache, wie sie von
BASIC her (für den PLAY-Befehl) bekannt ist:
Seite 66
RGH-PROFAN²
A..G
On
>
<
Ln
Pn
Tn
MN
ML
MS
In
Kn
Vn
entsprechende Note:
#
- Erhöhung
+
- Erhöhung
- Erniedrigung
.
- Punktiert
n
- kennzeichnet die Notenlänge. 4 steht für Viertel, 2 für Halbe, etc.
Wird n weggelassen, wird die Standardlänge verwandt.
Oktave n (0..6) wird gewählt
Eine Oktave höher
Eine Oktave niedriger
Setzt die Standardlänge
Pause in der Länge n.
Tempo: Anzahl der Viertelnoten pro Minute. Defaultwert ist 120.
normale Musik. Jede Note wird 7/8 der Zeit gespielt
Legato. Die Töne gehen in einander über.
Staccato. Jede Note wird nur 3/4 der Zeit gespielt.
Instrument n (0 ... 127) wird auf den aktuellen MIDI-Kanal gelegt. *
MIDI-Kanal n (0..15) wird wiedergegeben. *
Der aktuelle Kanal wird auf Lautstärke n (0...127) eingestellt. *
* Diese Befehle wirken nur bei einer Soundkarte.
Um eine Tonleiter in Viertel-Noten in der 4. Oktave zu spielen, reicht folgender Befehl:
MUSIC "O4 C4 D4 E4 F4 G4 A4 B4 > C4"
Erhöhungs- und Erniedrigungszeichen sind genauso möglich, wie auch Punktierungen:
MUSIC "C#2 F-8 G4."
Pausen haben den Notenwert "P".
Der Befehl MUSIC gibt bei vorhandenem MIDI-Gerät (Soundkarte oder MIDI-Schnittstelle)
die Musik über das MIDI-Gerät aus. Die Musik-Makrosprache von PROFAN² wurde dazu um
folgende Befehle erweitert: I (Instrument), V (Volume/Lautstärke) und K (Kanal). Die
Tonleiter gespielt mit der Kirchenorgel in voller Lautstärke:
MUSIC "I019 V127 O4 C4 D4 E4 F4 G4 A4 B4 > C4"
Beachten Sie, daß beim MUSIC-Befehl die Zählung der Instrumente bei 0 beginnt.
HINWEIS: In der 32-Bit-Version von PROFAN² für Windows 95 bzw. Windows NT wird die
Soundwiedergabe mit PLAY und MUSIC ohne Soundkarte nicht mehr unterstützt, da
Windows dort diese nicht mehr vorsieht. In der 16-Bit-Version wird in diesen Fällen (auch
wenn die Programme unter Windows 95 oder NT gestartet werden) der PC-Lautsprecher
bemüht.
Wer eine Soundblasterkompatible Karte hat oder auf andere Weise die WindowsSounddateien mit der Endung WAV hat, wird sich über den PLAYSOUND-Befehl freuen.
Jede WAV-Datei kann damit abgespielt werden:
PLAYSOUND "SIRENE.WAV", 1
Der letzte Paramater bestimmt den Abspiel-Modus. Sinnvolle Parameter sind:
019-
Die Datei wird im Vordergrund gespielt. Das Programm wird solange angehalten.
Die Datei wird im Hintergrund gespielt. Das Programm läuft weiter.
Die Datei wird im Hintergrund gespielt und solange wiederholt, bis ein neuer
PLAYSOUND-Befehl kommt.
Seite 67
RGH-PROFAN²
19 - Multimediaschnittstelle
Eine der interessantesten Neuerungen von Windows 3.1 war die Erweiterung um
Multimediafähigkeiten. Es wurde eine Multimedia-Schnittstelle geschaffen, mit der alle
möglichen (und zukünftigen) Multimediageräte angesprochen werden können. Diese
Schnittstelle ist das MCI, das "Media-Control-Interface. Über die Funktion @MCISEND$
kann PROFAN² mit dieser Schnittstelle kommunizieren. Alle angeschlossenen Geräte
können über diese Funktion mit einfachen, fast umgangssprachlichen (englischen)
Kommandos steuern. Ist das Kommando erfolgreich ausgeführt worden, hat %MCIERROR
den Wert 0 und der zurückgemeldete String enthält die angeforderte Information oder
einfach "OK". Ist ein Fehler aufgetreten, ist der Rückgabestring die Fehlermeldung.
Was sind Multimediageräte? Multimediageräte sind die Programme zum Abspielen von
WAV-Dateien, MIDI-Dateien und neuerdings auch VIDEO-Dateien ebenso, wie z.B. der CDSpieler (das CD-ROM-Laufwerk als Audiogerät). Um ein solches "Gerät" zu nutzen, muß es
erst einmal geöffnet werden. Dazu dient der Befehl OPEN, gefolgt vom Geräte- bzw.
Dateinamen. Zur Vereinfachung der weiteren Befehle kann diesem Gerät mittels ALIAS ein
Name zugewiesen werden, der bis zum CLOSE-Befehl gilt.
Da es an dieser Stelle nicht möglich ist, alle MCI-Befehle aufzuführen, möchte ich
wenigstens die wichtigsten Befehle in Programmzeilen bzw. Bespielprogrammen darstellen:
19.1 CD-Player
Dieses Programmzeilen spielen die Titel 3 bis 5 der eingelegten CD.
@MCISend$(open cdaudio alias cd")
Print "Länge: ";@MCISend$("status cd length")
Print "Titelzahl: ";\
@MCISend$("status cd number of tracks")
@MCISend$("set cd time format tmsf")
@MCISend$("play cd from 3 to 5")
Das Zeitformat "tmsf" bedeutet, daß Start und Ende im PLAY-Befehl im Format
"Track:Minute:Sekunde:Frame" angegeben werden, wobei eine Sekunde 75 "Frames"
(kleinste Einheit) hat. Es können also beliebige Bruchstücke eines Titels gespielt werden. Die
folgenden Zeilen halten die CD an und schließen das Gerät.
@MCISend$("stop cd")
@MCISend$("close cd")
Weitere interessante MCI-Befehle im Zusammenhang mit Audio-CDs:
SET CD DOOR OPEN
SET CD DOOR CLOSED
STATUS CD CURRENT TRACK
STATUS CD LENGTH
STATUS CD LENGTH TRACK Nr
STATUS CD MODE
STATUS CD POSITION
öffnet das CD-Fach
schließt CD-Fach
Nummer des aktuellen Titels
Länge der CD
Länge des Titels Nr
augenblicklicher Modus
aktuelle Position im Zeitformat
Wird ein anderer Alias-Name gewählt, ist das Wort "CD" entsprechend abzuändern.
Seite 68
RGH-PROFAN²
19.2 WAV-Dateien
Ausgabe einer "WAV"-Datei: Mit folgenden Zeilen wird eine WAV-Datei gespielt:
@MCISend$("open gong.wav type waveaudio alias gong")
@MCISend$("play gong") 'Datei spielen
...
@MCISend$("close gong") '... schließen
Zwischen PLAY und CLOSE muß natürlich genug Zeit gelassen werden, die Datei zu spielen
oder es muß ein "wait" eingefügt werden, um solange zu warten, bis der Befehl ausgeführt
ist:
@MCISend$("play gong wait")
Der Zusatz "wait" ist mit Vorsicht einzusetzen, da Windows solange keine anderen
Ereignisse zuläßt!
Mit folgendem Programm können beliebige WAV-Dateien abgespielt werden. Ein Mausklick
bricht die aktuelle WAV-Datei ab und zeigt erneut die Datei-Auswahlbox an. (Gewiß, es
ginge auch mit dem PROFAN²-Befehl PLAYSOUND, aber der ist nicht Thema dieses
Kapitels!)
CLS
Declare A$,B$
WindowTitle "WAV-Player"
Let A$=@LoadFile$("KLANG-DATEI","*.WAV")
While @NEQ$(A$,"")
Let A$=@ADD$(@ADD$("OPEN ",A$),\
" TYPE WAVEAUDIO ALIAS SOUND")
Let B$=@MCISend$(A$)
Case %MCIError : Print "Fehler: ";B$
Let B$=@MCISend$("PLAY SOUND")
WaitMouse
Let B$=@MCISend$("CLOSE SOUND")
Let A$=@LoadFile$("KLANG-DATEI","*.WAV")
Wend
End
WAV-Datei per Mikro aufnehmen: Folgende Zeilen nehmen eine WAV-Datei über das
Mikrofon auf:
@MCISend$("open new type waveaudio alias test")
@MCISend$("set test time format milliseconds")
@MCISend$("record test from 0 to 5000 wait")
Nach der Aufnahme spielen wir sie ab und können sie auch abspeichern.
@MCISend$("Play test from 0 wait")
@MCISend$("save test test.wav")
Seite 69
RGH-PROFAN²
Weitere Interessante Befehle für WAV-Dateien:
PLAY DT FROM x TO y
spielt von x bis y
SEEK DT x
positioniert bei x im Zeiformat
DELETE DT FROM x TO y
löscht einen Teil der Datei
INFO DT FILE
Dateinamen der Datei
STATUS DT LENGTH
Länge der Datei im Zeitformat
STATUS DT POSITION
Aktuelle Position in der Datei
STATUS DT TIME FORMAT
Aktuelles Zeitformat
SET DT TIME FORMAT BYTES
stellt Zeitformat "Bytes" ein
SET DT TIME FORMAT MILLISECONDS
Zeitformat in Millisekunden
"DT" steht hier für den Aliasnamen der entsprechenden Datei. Diese Befehle und Funktionen
gelten im übrigen auch für MIDI- und VIDEO-Dateien.
19.3 MIDI-Dateien
Da MIDI-Dateien den WAV-Dateien recht ähnlich sind, was die Ansteuerung durch MCI
betrifft, hier nur ein kurzes Beispielprogramm:
Cls
Declare A$,B$
WindowTitle "MIDI-PLAYER"
Let A$=@LOADFILE$("MIDI-DATEI","*.MID")
While @NEQ$(A$,"")
Let A$=@ADD$(@ADD$("OPEN ",A$),\
" TYPE SEQUENCER ALIAS MIDI")
Let B$=@MCISend$(A$)
Case %MCIError: Print "Fehler: ";B$
Let B$=@MCISend$("PLAY MIDI")?
WaitMouse
Let B$=@MCISend$("CLOSE MIDI")
Let A$=@LOADFILE$("MIDI-DATEI","*.MID")
Wend
End
Seite 70
RGH-PROFAN²
19.4 Video für Windows
Ein Beispiel für das Abspielen von Filmen ist Microsofts "Video für Windows". Mit folgendem
Programm können dieses Videodateien abgespiel werden, sofern zumindest die RuntimeVersion von Video für Windows installiert ist:
Cls
Declare A$,B$
WindowTitle "Testprogramm AVI-Video"
Let A$=@LOADFILE$("FILM-DATEI","*.AVI")
While @NEQ$(A$,"")
Let A$=@ADD$(@ADD$("OPEN ",A$),\
" TYPE AVIVIDEO ALIAS FILM")
Let B$=@MCISend$(A$)
Case %MCIError: Print "Fehler: ";B$
Let B$=@MCISend$("PLAY FILM")
WaitMouse
Let B$=@MCISend$("CLOSE FILM")
Let A$=@LOADFILE$("FILM-DATEI","*.AVI")
Wend
End
Das Abspielen anderer Animationen, etwa von *.FLI- oder *.FLC-Dateien des AutdeskAnimators sieht sehr ähnlich aus, nur daß dann eben hinter TYPE ein anderer Begriff steht.
Selbstverständlich müssen dazu die entsprechenden Autodesk-Treiber installiert sein.
Genauso ist es auch mit Treibern für Apples Quicktime-Videos oder für MPEG-Filme.
Weitere interessante Informationen zum Thema MCI finden sich in der einschlägigen
Fachliteratur bzw. den Handbüchern zu den entsprechenden Treibern und Produkten.
Seite 71
RGH-PROFAN²
20 - Datenbanken
PROFAN² ist auch eine komplette Datenbanksprache. Einfache bis mittlere DatenbankAnwendungen können mit PROFAN problemlos realisiert werden. Das Gebiet reicht von
einer einfachen Adreßverwaltung bis hin zu einer Kundenverwaltung mit Artikeln,
Rechnungen etc. Die wesentlichen Leistungsmerkmale im Überblick:
Datentabellen und Indizes im DBase-III-Format. Das heißt: Volle Kompatibilität zu allen
DBase-kompatiblen Datenbanken. Beim Zugriff auf DOS-Datenbanken sollten Sie mit
@ANSITOOEM$ bzw. @OEMTOANSI$ die unterschiedlichen Zeichensätze berücksichtigen
oder mit FONT den OEM-Zeichsdatz einstellen.
Seit Version 4.5a können Sie mit dem Befehl FONT festlegen, welchen Zeichensatz
PROFAN² in den dBase-III-Tabellen benutzt! Bei 1 wird der OEM-Zeichensatz gewählt.
Dieser ist dann zu verwenden, wenn etwa von anderen Programmen auf die Daten
zugegriffen werden soll. Diese erwarten bei einer dBase-III-Datei in der Regel den ASCIIbzw. OEM-Zeichensatz; das gilt auch für die ODBC-Treiber.
Was Größe und Struktur betrifft, wurde das dBase-Format etwas aufgebohrt: max. 1024
Felder pro Datensatz, max. 16000 Bytes pro Datensatz, max. ca. 2 Milliarden Sätze pro
Tabelle. Es können gleichzeitig bis zu 15 Datenbanktabellen geöffnet sein.
Ab Version 3.2 besitzt PROFAN² nun auch eine einfache ODBC-Schnittstelle, um auf andere
Datenbanken zugreifen zu können. So empfiehlt sich PROFAN² auch als Frontend bzw.
Client in einer Client-Server-Umgebung.
20.1 Datenbank-Grundlagen
Einige Hinweise zur Nomenklatur: Da in der Literatur von Datenbanksystem zu
Datenbanksystem unterschiedliche Begriffe für gleiche Sachverhalte (schlimmer noch: auch
gleiche Begriffe für verschiedene Sachverhalte) verwandt werden, will ich hier die in dieser
Anleitung gebrauchten kurz klären:
Wenn ich z.B. eine Adresse abspeichern will, so besteht diese aus verschiedenen Teilen: Da
gibt es z.B. den Vornamen, den Nachnamen, die Straße, den Ort, ... Dieses sind die
einzelnen "Felder" der Adresse.
Wenn ich mehrere Adressen speichere, so haben alle Adressen die gleichen Felder: Jede
Adresse besteht aus Vorname, Nachname, ... Jede einzelne Adresse ist ein "Datensatz".
Mehrere Datensätze mit der gleichen Struktur (d.h. den gleichern Feldern) bilden eine
"Tabelle" (bzw. Datenbanktabelle). Wenn ich von der "Struktur" einer Tabelle rede, dann
rede ich darüber, aus welchen Feldern jeder Datensatz der Tabelle aufgebaut ist.
Größere Anwendungen kommen nicht mit einer Tabelle aus. Eine Kundenverwaltung
benötigt vielleicht eine Tabelle mit Kundenadressen, eine weitere mit Rechnungen, eine
dritte mit Artikeln, etc. All diese Tabellen bilden die "Datenbank". (Im DBase-Bereich wird
manchmal auch von einer Tabelle als "Datenbank" gesprochen, das ist aber nicht korrekt.)
Häufig nennt man die Tabellen auch "Entityset" und den Datensatz ein "Entity".
Seite 72
RGH-PROFAN²
20.2 Datenbankstrukturen und Tabellen
Bevor in eine Datenbanktabelle der erste Datensatz (englisch: Record) geschrieben werden
kann, muß diese Tabelle erzeugt werden. Zum Erzeugen der Tabelle gibt es den Befehl
dbCREATE. Dieser benlötigt eine Strukturdatei, die die Struktur der Tabelle beschreibt. Die
Strukturdatei ist eine reine ASCII-Datei, die für jedes Feld der Datenbanktabelle eine Zeile
enthält. Diese Zeile enthält durch Semikolons getrennt nacheinander den Namen des Feldes,
dessen Typ, dessen Länge und die Anzahl der Dezimalstellen. Es müssen immer alle vier
Eigenschaften angegeben werden. PROFAN² kann die Feldtypen C=Text, D=Datum,
N=Zahlen, M=Memofeld und L=Ja/Nein bearbeiten.
Beispiel einer Strukturdatei:
NAME;
VORNAME;
STRASSE;
PLZ_ORT;
TELEFON;
GEBURT;
GEHALT;
NOTIZ;
C;
C;
C;
C;
C;
D;
N;
M;
30;
30;
30;
30;
20;
8;
10;
10;
0
0
0
0
0
0
2
0
Der Name eines Feldes darf nur aus Großbuchstaben (Kleinbuchstaben werden automatisch
umgewandelt), Ziffern und dem Unterstrich bestehen. Ein Feldname darf maximal zehn
Zeichen lang sein und darf nicht mit einer Ziffer beginnen.Wenn Sie eine Datenbanktabelle
mit obiger Struktur erzeugen wollen, geben Sie die Struktur wie gezeigt im Windows-Editor
(oder auch mit PROFED) ein und speichern Sie unter einem Namen, z.B. "ADRESS.STR"
ab. Mit der Befehlszeile
dbCreate "ADRESS.STR" > "ADRESS.DBF"
erzeugen Sie nun die noch leere Datenbanktabelle. Wesentlich komfortabler können Sie
Datenbanktabellen mit dem "Helfer" für Datenbankstrukturen erzeugen, mit dem "StrukturEditor", den Sie im Menü "Helfer" der Entwicklungsumgebung finden.
Natürlich können Sie mit PROFAN² auch die Struktur einer fremden oder unbekannten
Datenbanktabelle (".DBF"-Datei) in Erfahrung bringen. Sie muß lediglich im DBase-Format
vorliegen. Im Beispiel wird die Struktur der Tabelle "ADRESS.DBF" ausgelesen:
Seite 73
RGH-PROFAN²
Declare Anzahl%,I%
Cls
@dbOpen(#1,"ADRESS.DBF")
@dbUse(#1)
Print "db-Struktur von ADRESS.DBF"
Print
Print "Datensätze:
";&dbRecCount
Print "Felder:
";%dbFCount
Print "Satzgröße:
";%dbRecSize;" Byte"
Print "Headergröße:
";%dbHeader;" Byte"
Print "Letzte Änderung: ";$dbLUpdate
Print
Let Anzahl% = %dbFCount
Let I% = 1
WhileNot @Gt(I%,Anzahl%)
@dbGetField$(I%)
Print $dbFName,$dbFType,%dbFLen,%dbFDecs
Inc I%
Wend
@dbClose(#1)
WaitKey
End
Zunächst wird die Tabelle mit @dbOPEN geöffnet. Da bis zu 15 Tabellen gleichzeitig
geöffnet sein können, wird im Beispiel der Tabelle die Nummer 1 zugewiesen. Mit @dbUSE
machen wir deutlich, daß sich die folgenden Zugriffe auf die Datenbank auf diese Tabelle mit
der Nummer 1 beziehen. Jetzt können wir über die entsprechenden Systemvariablen die
Merkmale der Datenbanktabelle in Erfahrung bringen. Dabei gibt die Systemvariable
%dbFCOUNT die Anzahl der Felder an.
In der nun folgenden WHILE-Schleife lesen wir mit @dbGETFIELD$ nacheinander alle
Felder des aktuellen Datensatzes und ermitteln über die entsprechenden Systemvariablen
die Eigenschaften der Felder. Da in unserem Beispiel @dbGETFIELDS nur dazu dient, um
das entsprechende Feld zum aktuellen Feld zu machen, interessiert uns das Ergebnis der
Funktion nicht.
20.3 Datenbanktabellen bearbeiten
Bevor eine Datenbanktabelle bearbeitet werden kann, muß sie geöffnet werden. Das
erreichen wir mit der Funktion @dbOpen. Als Ergebnis liefert die Funktion die Anzahl der
Datensätze der geöffneten Tabelle zurück. Als Parameter wird zunächst die
Tabellenkennung (eine Nummer von 1 - 15) erwartet und dann der Dateiname der Tabelle.
Da wir insgesamt bis 15 Tabellen gleichzeitig geöffnet haben können, müssen wir als
nächstes mit der Funktion @dbUse angeben, welche Tabelle wir bearbeiten wollen:
Cls
Declare Anzahl%
Let Anzahl% = @dbOpen(#1,"ADRESS.DBF")
@dbUse(#1)
Print "ADRESS.DBF hat",Anzahl%,"Datensätze!"
Jetzt können wir zum Beispiel einen Datensatz hinzufügen:
Seite 74
RGH-PROFAN²
@dbAppendBlank()
@dbPut("NAME","Mustermann")
@dbPut("VORNAME","Max")
@dbPut("STRASSE","Sackgasse 13")
@dbPut("PLZ_ORT","98765 Nirgendwo")
@dbPut("TELEFON","09876/54321")
@dbPut("GEBURT",@CToD$("23.09.1955"))
@dbPut("GEHALT","4500.50")
@dbPutRec(0)
Mit @dbAPPENDBLANK wird ein neuer leerer Datensatz im Arbeitsspeicher erzeugt. Er wird
hinter dem letzten bestehenden Datensatz positioniert. Mit @dbPut wird den einzelnen
Feldern dieses Datensatzen ein Wert zugewiesen. Der erste Paramerer ist der Name des
Feldes und der zweiter der Wert, bzw. der Text, den das Feld bekommen soll. Im Falle des
Datumsfeldes wird das Datum zunächst mit @CTOD$ in das Datenbankformat
umgewandelt. Die Funktion @dbPUTREC schreibt den Datensatz aus dem Arbeitsspeicher
in die Tabelle. Der Parameter ist die Nummer des Datensatzes. Wird hier - wie in unserem
Beispiel - eine Null
angegeben, wird der Datensatz an die aktuelle Position
zurückgeschrieben. Vor dem Ende des Programmes sollte die Tabelle in jedem Fall mit
@dbCLOSE geschlossen werden:
@dbClose(#1)
Mit folgendem Programm könnten wir den Datensatz wieder auslesen und auf den
Bildschirm bringen:
Cls
Declare Anzahl%
Let Anzahl% = @dbOpen(#1,"ADRESS.DBF")
@dbUse(#1)
Print "ADRESS.DBF hat",Anzahl%,"Datensätze!"
@dbGo("|<")
Print "Name:
",@dbGet$("NAME")
Print "Vorname:
",@dbGet$("VORNAME")
Print "Straße:
",@dbGet$("STRASSE")
Print "PLZ Ort:
",@dbGet$("PLZ_ORT")
Print "Telefon:
",@dbGet$("TELEFON")
Print "Geburtstag:",@DToC$(@dbGet$("GEBURT"))
Print "Gehalt:
",@dbGet$("GEHALT")
@dbClose(#1)
Nach dem Öffnen der Tabelle wird mit @dbGO auf den ersten Satz der Datenbank
positioniert. Mit dieser Funktion können wir auf den ersten Satz positionieren ("|<"),
zurückblättern ("<"), vorwärtsblättern (">") und auf den letzten Satz positionieren (">|").
Ebenso könnten wir als Parameter eine bestimmte Satznummer angeben.Mit @dbGET$ wird
der Inhalt des aktuellen Datensatzes gelesen, wobei der Parameter der Name des
entsprechenden Feldes ist. Mit @dbDELETE könnten wir den aktuellen Datensatz auch als
gelöscht markieren. Wohlgemerkt: er wird lediglich als gelöscht gekennzeichnet. Ob ein
Datensatz als gelöscht gekennzeichnet ist, bringen wir durch die Systemvariable
%dbDELETED in Erfahrung. Um alle als gelöscht gekennzeichneten Datensätze der Tabelle
wirklich (und endgültig) zu löschen, muß die Funktion @dbPACK aufgerufen werden.
Natürlich können wir den aktuellen Datensatz mit @dbPUT verändern und dann mit
@dbPUTREC in die Datenbank zurückschreiben.
Ab Version 4.2 kann mit @DBGETMEMO der Text eines Memo-Feldes aus der Memo-Datei
Seite 75
RGH-PROFAN²
in die Listboxliste eingelesen und mit @DBPUTMEMO der Inhalt der Listboxliste in ein
Memo-Feld geschrieben werden. Zum Editieren des Inhaltes der Listboxliste bietet sich die
Funktion @EDITBOX an. Im Zuge dieser Erweiterung wurde nun auch dafür Sorge getragen,
daß mit @DBPUT bzw. @DBPUTFIELD der Inhalt eines Memofeldes nicht geändert werden
kann. Ein versehentliches Ändern der Verweise auf die Memo-Datei würde im harmlosensten
Fall dazu führen, daß der Text nicht mehr gefunden wird. Beide Funktionen geben nun 0
zurück, wenn ein Fehler auftrat. Ob eine Tabelle Memo-Felder enthält, können wir mittels der
Systemvariablen %DBMEMO überprüfen.
Folgende Prozedur ermöglicht also das Lesen, Editieren und Schreiben eines Memo-Feldes
(entsprechend MEMOEDIT in dBase):
PROC MEMOEDIT
Parameters FeldName$
@DBGETMEMO(FeldName$)
IF @EDITBOX("Memo editieren",1)
@DBPUTMEMO(FeldName$)
ENDIF
ENDPROC
Aufgerufen wird die Prozedur mit dem Feldnamen des Memofeldes als Parameter, z.B.
MEMOEDIT "NOTIZ"
Wenn wir viele Datensätze eingegeben haben, wollen wir sie auch sortiert anzeigen können.
Hierzu benötigen wir einen Index, d.h. eine extra Datei, die die Sortierreihenfolge enthätt.
Auch bei den Indizes unterstützt PROFAN² den dBase-III-Standard. Bevor solch eine IndexDatei genutzt werden kann, müssen wir sie zunächst erzeugen. Das geschieht mit dem
Befehl dbCREATEINDEX. Um zum Beispiel unsere Adreß-Tabelle nach Namen zu sortieren
erzeugen wir den entsprechenden Index:
dbCreateIndex "NAME" > "INAME"
Der erste Parameter ist der Name des betroffenen Feldes und der zweite der Name der
erzeugten Indexdatei. Die Dateiendung ".NDX" wird automatisch angehängt und darf nicht
mit angegeben werden. Wollen wir aber nach Namen UND Vornamen sortieren, so können
wir auch beide Feldnamen mit "+" verbunden angeben:
dbCreateIndex "NAME+VORNAME" > "INAME"
Um diese Sortierreihenfolge zu nutzen, müssen wir dem Programm nun noch mitteilen, daß
die entsprechende Index-Datei zu öffnen ist. Das geschieht mit der Funktion
@dbINDEX. Beispiel:
@dbIndex("INAME")
Die Funktion gibt Null zurück, wenn der Index nicht geöffnet werden konnte, etwa weil die
Indexdatei nicht existiert oder keine Datenbanktabelle geöffnet ist. Wurde der Index geöffnet,
beziehen sich die folgenden @dbGO-Anweisungen auf diese Sortierreihenfolge.
Oftmals will man in einer Datenbank nach einem bestimmten Eintrag suchen. Liegt auf dem
Feld, das diesen Eintrag enthält, ein Index, geht die Suche besonders schnell mit der
Funktion @dbFIND:
@dbIndex("INAME")
Let SatzNr& = @dbFind("Mustermann",1)
Es wird der erste Datensatz gefunden, der mit dem Suchbegriff (in unserem Beispiel
"Mustermann") identisch ist. Der zweite Parameter bei @dbFIND gibt an, wie exakt gesucht
werden soll. Hat er den Wert 0, so genügt es für eine erfolgreiche Suche, wenn der das
entsprechende Feld des Datensatz mit dem Suchbegriff beginnt. War die Suche nicht
erfolgreich, gibt die Funktion @dbFIND den Wert Null zurück.
Seite 76
RGH-PROFAN²
Die Funktion @dbSEEK sucht ohne Index in jedem beliebigen Feld nach dem Suchbegriff.
Beispiel:
Let SatzNr& = @dbSeek("STRASSE","gasse")
Der erste Parameter ist der Name des Feldes, in dem gesucht werden soll, und der zweite
Parameter ist der Suchbegriff. Ausgehend vom aktuellen Datensatz wird der nächste
Datensatz gefunden, der den Suchbegriff im gewünschten Feld enthält. Auf diesen Datensatz
wird positioniert. Über einen optionalen dritten Parameter kann auch hier die
Suchgenauigkeit festgelegt werden.
Wenn man sich z.B. mit @dbGO(">") durch eine Tabelle bewegt, kommt man irgendwann
zum letzten Datensatz. In diesem Fall wird die Systemvariable %dbEOF auf den Wert eins
gesetzt, will heißen: Das Datei-Ende ist erreicht. Die augenblickliche Satznummer findet sich
in der Systemvariablen &dbRecNo.
Die FeldTypen:
Feldtyp "C" - Text
Der Feldtyp "C" (Character) kann einen String (max. Länge: 254 Zeichen) aufnehmen. Bei
der Definition der Struktur muß die Länge des Feldes (1 - 254) mit angegeben werden. Der
String darf beliebige Zeichen enthalten.
Feldtyp "D" - Datum
Der Feldtyp "D" (Date) enthält ein Datum. Das Datum wird immer im Format JJJJMMTT
gespeichert. Aus dem 23.09.1955 würde somit der Feldinhalt "19550923". Der Vorteil dieser
Schreibweise ist der, daß einerseits Daten miteinander korrekt verglichen werden können
(ein späteres Datum ist immer größer als ein früheres) und andererseits mit dem Inhalt sogar
gerechnet werden kann. Um ein Datum in vernünftiges europäisches Format umzuwandeln,
gibt es die Funktion @DToC$. Soll ein Datum, das im europäischen Format ("TT.MM.JJJJ")
vorliegt in ein Datenbankfeld geschrieben werden, muß es mit der Funktion @CToD$ zuvor
in das Datenbankformat umgewandelt werden.
Feldtyp "N" - Zahlen
Der Feldtyp "N" (Numeric) enthält Zahlen, numerische Werte. Ein solches Feld kann eine
Länge zwischen 1 und 19 Zeichen haben, wobei in diesen max. 19 Zeichen auch der
Dezimalpunkt und das Vorzeichen enthalten ist. Zusätzlich zur Längenangabe benötigen wir
bei numerischen Feldern noch die Angabe der Dezimalstellen. Um z.B. Werte zwischen "999999.99" und "999999.99" darstellen zu können, benötigen wir ein numerisches Feld mit
der Länge 10 und 2 Dezimalstellen.
Feldtyp "L" - Ja/Nein
Der Feldtyp "L" (Logical) enthält einen logischen Wert, also entweder "WAHR" oder
"FALSCH". "WAHR" wird in der Datenbank durch "T" (True) oder "Y" (Yes) dargestellt und
"FALSCH" durch "F" (False) oder "N" (No). Ein logisches Feld hat also immer die Länge 1
und darf nur einen der vier genannten Buchstaben enthalten. Unter Windows wird man ein
logisches Feld in der Eingabemaske in der Regel durch eine Checkbox darstellen.
Seite 77
RGH-PROFAN²
Feldtyp "M" - Memo-Feld
Memo-Felder haben in der Datenbank-Datei (der DBF-Datei) eine konstante Länge von 10.
Der Inhalt dieser Datei ist ein Verweis auf den Anfang des zugehörigen Textes in der MemoDatei. Diese hat den gleichen Dateinamen wie die DBF-Datei mit der Endung DBT. Ob eine
DBF-Datei überhaupt Memo-Felder hat, kann nach dem Öffnen der Tabelle mit der
Systemvariablen %DBMEMO festgestellt werden.
Seite 78
RGH-PROFAN²
20.4 ODBC-Schnittstelle
PROFAN² unterstützt nun auch die Programmierung der ODBC-Schnittstelle, wenn sie auf
dem Rechner installiert ist.
ODBC ist ein Datenbankstandard, der inzwischen von allen wichtigen Datenbankherstellern
unterstützt wird. Datenbanken, die diese Schnittstelle unterstützen, haben einen
entsprechenden Treiber, der über die Windows-Systemsteuerung konfiguriert werden kann.
In der Systemsteuerung findet sich eigens ein Icon für die ODBC-Treiber. Über diesen
Treiber kann auf den Datenbankserver (z.B. ORACLE, DB2, SQLServer, ...) zugegriffen
werden. Es gibt aber auch Treiber, um die ACCESS-, dBASE- oder PARADOX-Tabellen als
Datenbankserver anzusprechen. Solche ODBC-Treiber werden z.B. mit WORD FÜR
WINDOWS 6.0 installiert. Auf der einen Seite haben wir also als Server (Lieferanten von
Daten) die Datenbank.
Auf der anderen Seite der Schnittstelle steht der Client (Kunde, Empfänger der Daten), der
über diese ODBC-Schnittstelle auf die Datenbank zugreift, d.h. Tabellen ändert und/oder
erweitert und vor allen Dingen auswertet. Die Sprache mit der dies geschieht heißt SQL, was
soviel wie "Strukturierte Abfrage-Sprache" bedeutet. SQL ist genormt, sodaß es egal ist,
welche Datenbank nun auf der anderen Seite als Server fungiert.
Über die ODBC-Schnittstelle kann nun ein PROFAN²-Programm als Client fungieren und auf
die Daten des Servers zugreifen. Damit dies möglich ist, muß zuerst die Verbindung zum
Server hergestellt werden. Das geschieht mit der Funktion @SQLINIT. Als Parameter wird
der Initialisierungs- bzw. Anmeldestring übergeben. Wenn als Parameter ein Leerstring
angegeben ist, wird in der Regel der SQL-Treiber ein Fenster öffnen, das eine Liste der
installlierten Datenbanktreiber anzeigen. Aus dieser Liste kann man dann den gewünschten
Treiber wählen. Anschließend muß die Datenbank ausgewählt werden. Im Falle von dBASEDateien gilt als Datenbank ein Verzeichnis, das die entsprechenden dBASE-Tabellen enthält.
Die Funktion @SQLINIT liefert 1 zurück, wenn die Anmeldung erfolgreich war, ansonsten 0.
Ist kein ODBC-Treiber installiert, wird die Fehlermeldung "ODBC-DLL nicht gefunden"
angezeigt.
Wie der Initialisierungsstring genau auszusehen hat, ist von Datenbank zu Datenbank
unterschiedlich. Entnehmen Sie die für Ihre Datenbank gültigen Angaben den
entsprechenden Handbüchern. Zwei Beispiele, darunter eines für dBase-Dateien mit dem
ODBC-Treiber von WinWord, finden Sie in der Referenz.
Um SQL-Befehle an die Datenbank zu senden, gibt es in PROFAN² den Befehl SQLExec.
Als ersten Parameter gibt es einen String, der einen gültiges SQL-Statement enthält. Der
zweite Parameter kennzeichnet bei SELECT-Anweisungen den Ausgabemodus. Diese
Einführung kann und will keine Einführung in SQL liefern. Diese finden Sie in der
entsprechenden Fachliteratur und den Handbüchern zu Ihrer Datenbank bzw. Ihrer SQLSchnittstelle. An dieser Stelle seinen nur die wichtigsten Anweisungen kurz aufgeführt:
Mit CREATE TABLE kann eine neue Tabelle erzeugt werden:
CREATE TABLE <Tabellenname> (<Feldname> <Feldtyp> [,...])
Der Feldtyp kann z.B. CHAR(N) sein, wobei N die Größe des Feldes ist; oder auch DATE
oder NUMERIC. Beispiel:
SQLExec "CREATE TABLE KUNDEN \
( VORNAME CHAR(25),\
NAME CHAR(25),\
GEBDAT DATE)",1
Im Falle einer dBASE-Datenbank würde
entsprechenden Feldern erzeugt werden.
die
Seite 79
Tabelle
"KUNDEN.DBF"
mit
den
RGH-PROFAN²
Um Datensätze hinzuzufügen wird der Befehl INSERT verwandt:
INSERT INTO <Tabellenname> (<Feldliste>)
VALUES (<Werteliste>)
Beispiel:
SQLExec "INSERT INTO KUNDEN (Vorname,Name) \
VALUES ('Hugo','Maier')",1
Geändert werden die Datensätze mit der UPDATE-Anweisung:
UPDATE <Tabellenname> SET <Feldname>=Inhalt [,...]
WHERE <Bedingung>
Beispiel:
SQLExec "UPDATE KUNDEN SET NAME = 'Mayer' \
WHERE NAME = 'Maier'",1
Zum Löschen dient der Befel DELETE:
DELETE FROM <Tabellenname> WHERE <Bedingung>
Die interessanteste Anweisung ist die SELECT Anweisung mit folgender Syntax:
SELECT [ALL|DISTINCT] <Feldliste>
FROM <Tabellenname>
[WHERE <Bedingung>]
[GROUP BY <Feldliste>]
[HAVING <Bedingung>]
[ORDER BY <Feldliste>]
In eckigen Klammern stehende Teile können weggelassen werden. ALL oder DISTINCT kann
wahlweise eingesetzt werden. Anstelle der ersten Feldliste kann auch ein * stehen, womit
dann alle Felder der Tabelle angezeigt werden.
Beispiele:
SQLExec "SELECT * FROM KUNDE",1
SQLExec "SELECT * FROM KUNDE WHERE NAME = 'Maier'",1
Alleine über die SELECT-Anweisung könnte man ein eigenes Buch schreiben (und viele
haben es auch getan), ganz zu schweigen von der JOIN-Klausel, mit der man Tabellen
relational verbinden kann. Es lohnt sich, einen Blick in die entsprechende Fachliteratur zu
werfen.
An dieser Stelle sei auch der zweite Parameter von SQLEXEC kurz erklärt: Bei 0 wird das
Ergebnis direkt angezeigt, bei 1 wird es in eine Listboxliste geschrieben und bei 2 wird es in
eine Datei geschrieben. Mit SQLSetDel und SQLSetNull kann das Ausgabeformat eingestellt
werden.
Die Anzahl der von SQLEXEC bearbeiteten Datensätze wird in &SQLCount zurückgeliefert.
Trat ein Fehler auf, wird -1 zurückgegeben. Der Befehl SQLDONE trennt die Verbindung
zum Server.
Seite 80
RGH-PROFAN²
Abschließend ein kleines Beispielprogramm, welches Zugriff auf die dBASE-Tabellen im
aktuellen Verzeichnis bietet. Es können beliebige SQL-Befehle ausprobiert werden. Beendet
wird das Programm, indem man bei der InputBox auf "Abbruch" klickt, bzw. "Esc" drückt.
Declare SQL$
Cls
If @SQLInit("DSN=dBase-Dateien")
Let SQL$=" "
WhileNot @Equ$(SQL$,"")
Let SQL$=@Input$("SQL-String eingeben:","PROFAN-SQL",SQL$)
IfNot @Equ$(SQL$,"")
ClearList
SQLExec SQL$,1
Print "Bearbeitet: ";&SQLCount;" Datensätze"
@ListBox$("Ergebnis:",2)
EndIf
Wend
SQLDone
EndIf
End
Seite 81
RGH-PROFAN²
21 - Dateien - Verzeichnisse - System - Zwischenablage
Ein BASIC-Programmierer wird sich etwas umstellen müssen, da mir das Dateisystem von
PASCAL flexibler erschien. In der aktuellen Version werden lediglich Textdateien unterstützt.
21.1 Dateien - Verzeichnisse - System
Unter Windows 95 unterstützen die hier beschriebenen Befehle und Funktionen automatisch
die langen Dateinamen auch in der 16-Bit-Version von PROFAN².
Dateien
Die meisten Befehle und Funktionen, die mit Dateien zu tun haben, erwarten als ersten
Parameter die Dateikennung, quasi ein Handle auf die Datei. Mittels ASSIGN wird einer
Dateikennung zwischen 1 und 8 der Name einer Datei zugewiesen. Bei den folgenden
Befehlen darf die Datei nicht geöffnet sein:
Um die Attribute einer Datei zu ermitteln, gib es die Funktion @GETFATTR. Mit SetFAttr
können die Attribute einer Datei verändert werden. Das Datum der letzten Änderung läßt sich
mit @GetFDate$ in Erfahrung bringen. Mit ERASE kann ich eine Datei löschen und mit
RENAME umbenennen bzw. innerhalb einer Festplatte verschieben.
Mit COPY kann eine Datei kopiert werden. Um herauszubekommen, welche Dateien
überhaupt vorhanden sind, gibt es die Funktionen @FINDFIRST$ und @FINDNEXT$. In
diesem Zusammenhang ist auch der Befehl ADDFILES interessant, mit dem der ListBoxListe
eine Liste der Dateien hinzugefügt wird, die dem Suchstring entspricht.
Verzeichnisse
Das aktuelle Laufwerk ist in der Systemvaraiblen $DRIVE abgelegt und den aktuellen Pfad
eines Laufwerkes ermittelt die Funktion @GETDIR$. Ebenso gibt es die Befehle MKDIR,
CHDIR und RMDIR zum Anlegen, Wechseln und Löschen eines Verzeichnisses.
System
Für Installationsprogramme ist es wichtig, das Windowsverzeichnis und das WindowsSystemverzeichnis zu erkennen. Das ermittle ich über die Systemvariablen $WINPATH und
$SYSPATH. In diesem Zusammenhang interessant sind auch die Systemvariablen
$DOSVER und $WINVER, die die Windows- und DOS-Version ermitteln.
HINWEIS: In der 32-Bit-Version von PROFAN² ist das Ergebnis von $DOSVER ohne
Bedeutung, da es dort kein von Windows unabhängiges DOS gibt.
Im Zusammenhang mit langen Dateinamen sei noch auf die Systemvariable %LFN
verwiesen, die in der 16-Bit-Version ermittelt, ob das Betriebssystem Windows 95 ist und
somit lange Dateinamen unterstützt werden.
Oft wird auch die Möglichkeit gebraucht, Windows zu verlassen und gegebenenfalls wieder
neu zu starten. Diese Möglichkeit ist mit dem Befehl EXITWINDOWS gegeben. Sind noch
Dateien offen, erfolgt natürlich eine Sicherheitsabfrage.
Seite 82
RGH-PROFAN²
Das Windowseigene Hilfesystem kann mit WinHelp aufgerufen werden. Dabei kann auch ein
Hilfethema gezielt angewählt werden, sodaß auch kontextsensitive Hilfe möglich ist. Um
Hilfedateien zu erzeugen, sei an dieser Stelle exemplarisch auf die Tools "Visual Help" und
"Help Magican" hingewiesen, die dies sehr vereinfachen. Sharewareversionen sollte jeder
gutsortierte Shareware-Händler im Angebot haben.
21.2 Textdateien (sequentielle Dateien)
In der Dateiverarbeitung werden grundsätzlich zwei verschiedene Zugriffsmethoden
unterschieden: Der sequentielle Zugriff auf Textdateien und der direkte (binäre) Zugriff auf
beliebige Dateien.
Das herausragende Merkmal des sequentiellen Zugriffs ist, daß nicht auf einen beliebigen
Datensatz zugegriffen werden kann, sondern immer nur - schön der Reihe nach - auf den
nächsten. Dafür können die Datensätze - hier Zeilen genannt - unterschiedliche Längen von
0 bis 255 Zeichen haben. Die einzelnen Datensätze sind durch ein Zeilenende-Zeichen
(@Chr$(13) und @Chr$(10)) voneinander getrennt. Sequentielle Dateien sind ideal, um
Textdateien zu bearbeiten, Highscore-Tabellen abzulegen, Programmparameter zu
verwalten etc. (Für andere Aufgaben, wie etwa Adressverzeichnis, Videokatalog etc. wird
man eher auf die Datenbankfunktionen von PROFAN² zurückgreifen, denen ein eigenes
Kapitel gewidmet ist.)
Um auf eine Datei zugreifen zu können, muß einer Dateinummer (Handle) eine physikalische
Datei zugewiesen werden. Das geschieht mit dem Befehl ASSIGN:
Assign #1,"C:\TEST.DAT"
Dateinummern von 1 bis 15 sind erlaubt. Mit dem ASSIGN-Befehl ist die Datei noch nicht
geöffnet. Dazu benötigen wir die Befehle RESET, REWRITE bzw. APPEND. RESET öffnet
die Datei zum Lesen. Mit REWRITE wird sie zum Neuschreiben geöffnet und mit APPEND
zum Anfügen. Wenn ich eine existierende Datei mit REWRITE öffne, wird sie - ohne jede
Warnung - gelöscht. Möchte ich an eine Datei zusätzlichen Text anhängen, ist APPEND zu
verwenden:
Assign #1,"C:\AUTOEXEC.BAT"
Append #1
Print #1,"REM Hinzufügen von Share"
Print #1,"SHARE"
Close #1
Eine Datei, die ich mit RESET öffne, kann ich mit INPUT# lesen:
Print "AUTOEXEC.BAT"
Print
Assign #2,"C:\AUTOEXEC.BAT"
Reset #2
If %IOResult
Print "Datei kann nicht geöffnet werden."
Else
WhileNot @EOF(#2)
Input #2, Zeile$
Print Zeile$
Wend
Close #2
EndIf
WaitKey
Seite 83
RGH-PROFAN²
HINWEIS: Standardmäßig wird beim Öffnen einer Datei, egal ob es zum Lesen oder
Schreiben geschieht, der FILEMODE 2 benutzt, d.h. dem Betriebssystem wird signalisiert,
das die Datei zum Schreiben und Lesen geöffnet werden soll. Ist die Datei nun
schreibgeschützt, wird das Betriebssystem sagen: Nein, das geht nicht! Damit auch eine
schreibgeschützte Datei (z.B,. auf CD-ROM) gelesen werden kann, muß vor dem RESETBefehle der FILEMODE 0 (nur lesen) eingestellt werden.
Geschlossen wird eine sequentielle (Text-)Datei mit CLOSE. Mit @EOF frage ich das Ende
einer Datei ab, die ich zum Lesen geöffnet habe. Wird in eine Datei geschrieben und
anschließend der Befehl CLOSE vergessen, gehen die geschriebenen Daten und
möglichweise der Inhalt der Datei verloren!
HINWEIS: Es solte nach Dateibefehlen immer mit %IOResult überprüft werden, ob auch
alles gut gegangen ist, da PROFAN² (wie auch PASCAL mit der Direktive $I-) keine
Fehlermeldung bringt, wenn etwas nicht funktioniert!
21.3 Binäre Dateien
PROFAN² kann auch binär auf Dateien zugreifen, d.h. jedes einzelne Byte kann gelesen,
verändert und geschrieben werden. Bevor eine Datei bearbeitet werden kann, muß ihr - wie
auch bei den sequentiellen Dateien - mit ASSIGN ein Handle zugewiesen werden. Um die
Datei zu öffnen, ist der Befehl OPENRW zu verwenden. Existiert die Datei bereits, wird sie
zum Bearbeiten geöffnet, anderenfalls wird sie erzeugt.
Soll eine bestehende Datei nur zum Lesen geöffnet werden, ist vor dem OPENRW der
Befehl FILEMODE 0 zu verwenden.
Nach dem Öffnen steht der Dateizeiger auf der ersten Position: auf 0, d.h. der nächste
Schreib- oder Lesezugriff würde das erste Byte in der Datei betreffen. Will man Daten an die
Datei anhängen, muß erst der Dateizeiger mit SEEK auf die erste Position nach dem
Dateiende gesetzt werden. Das geschieht z.B. mit dem Befehl:
SEEK #1,@GETFILESIZE(#1)
Mit @GETFILESIZE wird die augenblickliche Größe der Datei in Bytes zu ermittelt. Dazu
muß die Datei geöffnet sein. (Hingegen kann mit @FILESIZE die Größe jeder ungeöffneten
Datei ermittelt werden.)
Mit @GETBYTE wird ein Byte aus einer mit OPENRW geöffneten Datei gelesen. Der
Dateizeiger wird auf das nächste Byte positioniert, sodaß der nächste Lesezugriff mit
@GETBYTE das nächste Byte liest. Wird das Dateiende erreicht, ergibt @EOF den Wert 1
(für WAHR).
Mit PUTBYTE kann ich in die Datei an der augenblicklichen Position des Dateizeigers
schreiben. Auch hier wird der Dateizeiger automatisch hochgezählt, sodaß das nächste Byte
richtigerweise an die nächste Position in der Datei geht. Wird durch häufige PUTBYTEBefehle das Dateiende überschritten wird die Datei entsprechend vergrößert.
Mit BLOCKWRITE können beliebig lange Teilstücke einer Bereichsvariablen in eine Datei
geschrieben werden. Ebenso kann nun mit @BLOCKREAD eine komplette Datei (in der 16Bit-Version von PROFAN² nur bis ca. 64 kB) in eine Bereichsvariable gelesen werden.
Natürlich können auch beliebige Teile einer binären Datei an beliebige Adressen einer
Bereichsvariablen gelesen werden.
Seite 84
RGH-PROFAN²
Es kann jederzeit mit SEEK der Dateizeiger neu positioniert werden. Wird er dabei hinter das
Ende der Datei gelegt, wird die Datei bis dorthin vergrößert.
Um die augenblickliche Position des Dateizeigers zu ermitteln, ist die Funktion @FILEPOS
zu verwenden.
WICHTIG: Nach der Bearbeitung muß die Datei mit CLOSERW wieder geschlossen werden,
da ansonsten Daten verloren gehen, auch wenn nicht in die Datei geschrieben wurde!
Zumeist findet man bei vergessenem CLOSERW nur noch eine 0 Byte große Ruine der
Datei auf der Festplatte vor! Eine mit OPENRW geöffnete Datei muß mit CLOSERW
geschlossen werden, da ansonsten ein Fehler auftritt!
HINWEIS: Es solte nach
Dateibefehlen immer mit %IOResult überprüft werden, ob auch alles gut gegangen ist, da
PROFAN² (wie auch PASCAL mit der Direktive $I-) keine Fehlermeldung bringt, wenn etwas
nicht funktioniert!
21.4 INI-Dateien
Für Windows spezifisch sind die INI-Dateien. Auch diese kann man von PROFAN² aus
schreiben und lesen. Dazu dienen die Funktion @READINI$ und der Befehl WRITEINI.
Wenn Konfigurationsdaten, Spielstände, etc. gespeichert werden sollen, ist die Nutzung von
INI-Dateien sehr zu empfehlen. Da sowohl Pfad als auch Dateiname angegeben werden
können, besteht kein zwingender Grund, INI-Dateien im Windowsverzeichnis abzulegen,
bzw. ihnen die Endung "INI" zu geben. Ins Windowsverzeichnis werden sie nur dann
abgelegt, wenn kein Pfad angegeben wird. Da @PAR$(0) Pfad und Name des aktuellen
Programmes wiedergibt, kann daraus der Programmpfad ermittelt werden und die INI-Datei
dort abgelegt werden.
Alle INI-Dateien sind gleich aufgebaut: Sie bestehen aus einem oder mehreren Abschnitten,
deren Titel in eckigen Klammern steht. Unter dem Titel stehen die einzelnen Einträge. Ein
Eintrag besteht aus einem Kennwort, gefolgt von einem Gleichheitszeichen und dem
zugehörigen Text. Ein Beispiel:
LET HighScore& = 25000
WRITEINI "SPIEL.INI","MeinProgramm",\
"HIGHSCORE"=@Str$(HighScore&)
Diese Zeilen würden folgende INI-Datei erzeugen:
[MeinProgramm]
HIGHSCORE=25000
Existiert die Datei noch nicht, wird sie erzeugt. Existiert in der Datei der Abschnitt noch nicht,
wird er hinzugefügt. Existiert im Abschnitt das Kennwort des Eintrages noch nicht, wird der
Eintrag hinzugefügt. Gibt es die INI-Datei mit dem Abschnitt und dem Eintrag schon, wird nur
der hinter dem Gleichheitszeichen stehende Text geändert.
21.5 Registry (nur 32 Bit)
In Windows 95 und Windows NT übernimmt die Registry, die Systemregistrierung, weitgehen
die Aufgaben der INI-Dateien. Auch die Registry wird mit @READINI$ und WRITEINI
bearbeitet.
Dabei wird anstelle des Dateinamens der INI-Datei die Klasse in der Registrierdatenbank
angegeben. Die recht langen Klassennamen werden durch die kürzeren Bezeichnungen
"HKEY_0" bis "HKEY_6" ersetzt:
Seite 85
RGH-PROFAN²
HKEY_CLASSES_ROOT
HKEY_CURRENT_USER
HKEY_LOCAL_MACHINE
HKEY_USERS
HKEY_PERFORMANCE_DATA
HKEY_CURRENT_CONFIG
HKEY_DYN_DATA
=
=
=
=
=
=
=
HKEY_0
HKEY_1
HKEY_2
HKEY_3
HKEY_4
HKEY_5
HKEY_6
Der zweite Parameter ist dann der komplette "Pfad" zum Eintrag. Der dritte Parameter ist der
Schlüssel (Key), der geschrieben werden soll. Ist der Pfad und/oder der Schlüssel nicht
vorhanden,m wird er angelegt. Sind Pfad und Schlüssel vorhanden, wird der entsprechende
Wert geändert. Der letzte Parameter ist der Wert, den der Schlüssel bekommen soll.
Einzelne Einträge des Pfades werden durch Backslashes (wie beim Verzeichnis)
voneinander getrennt:
Bei einem 32-Bit-Spiel könnte der Highscore etwa wie folgt gespeichert werden:
LET HighScore& = 25000
WriteIni "HKEY_1","RGH-Soft\Spiele\MeinProgramm", \
"High-Score"=@Str$(HighScore&)
Wollten wir jetz auch noch weitere Optionen speichern, könnten wir im selben Pfad einen
anderen Schlüssel verwenden, etwa für die Sound-Einstellung:
WriteIni "HKEY_1","RGH-Soft\Spiele\MeinProgramm","Sound"="EIN"
Diese Zeile würde in der 16-Bit-Version im übrigen keinen Fehler produzieren, sondern eine
INI-Datei "HKEY_1" im Windowsverzeichnis mit einem entsprechenden Eintrag erzeugen.
Das kann durchaus gewollt sein und ermöglicht es, Programme zu schreiben, die unter 32 Bit
die Registry nutzen und unter 16 Bit entsprechende INI-Dateien. Aus diesem Grund wurden
statt der langen Klassennamen auch die kurzen Versionen HKEY_0 bis HKEY_6 für die
PROFAN²-Syntax gewählt.
ACHTUNG: Seien Sie vorsichtig beim Überschreiben bestehender Registry-Einträge!
Ebenso wie es durch Ändern von SYSTEM.INI oder WIN.INI möglich ist, Windows
weitgehend lahmzulegen, ist dies auch mit Änderungen der Registry noch viel effektiver
möglich!
Seite 86
RGH-PROFAN²
21.6 Die Zwischenablage
PROFAN² unterstützt auch die Möglichkeit, Daten über das Clipboard (Zwischenablage)
auszutauschen. PROFAN² kann mit PUTCLIP einen String in die Zwischenblage schreiben
und mit @GETCLIP$ Text aus der Zwischenablage in einen String lesen. Mit CLEARCLIP
wird die Zwischenablage gelöscht. Das eröffnet interessante Möglichkeiten des
Datenaustausches (nur Text) mit anderen Programmen oder der Fernsteuerung eines
PROFAN²-Programmes durch ein anderes.
Mit SAVEBMPTOCLIP wird ein Bereich des Bildschirmes in die Zwischenablage kopiert und
mit CLIPLOADBMP wird der Inhalt der Zwischenablage - so er eine Bitmap ist - mit dem
angegebenen Abbildungsmodus auf den Bildschirm gebracht:
CLEARCLIP
SAVEBMPTOCLIP 0,0-180,180
CLIPLOADBMP 100,100;0
In diesem Zusammenhang sind auch die Botschaften wm_cut, wm_paste, wm_clear und
wm_copy interessant mit denen z.B. auch Editierfelder oder gar andere Anwendungen
angesprochen werden können. Mit @SENDMESSAGE werden die entsprechenden
Botschaften an die Fensterelemente geschickt. Die wichtigsten Botschaften werden im
entsprechenden Teil der Online-Hilfe ausführlich dargestellt.
21.7 Windows 95 und lange Dateinamen
Ab Version 4.1 unterstützt PROFAN² vollautomatisch die langen Dateinamen unter Windows
95.
Im Regelfall kann es dem PROFAN²-Programmierer bei 16-Bit-Programmen egal sein, auf
welchem Zielsystem das Programm eingesetzt wird. Das Programm erkennt automatisch, ob
es unter Windows 3.x oder Windows 95 gestartet wurde und reagiert entsprechend: Die
Load- und Save-Dialoge werden an lange Dateinamen angepaßt und auch alle anderen
Funktionen und Befehle können nun mit langen Dateinamen umgehen. (Eine Ausnahme
bilden die Dateinamen von Datenbanktabellen und Indexdateien).
In einigen Spezialfällen mag es aber sein, daß der Programmierer bewußt mit langen
Dateinamen umgehen will. Hier bietet PROFAN² an Version 4.1 einige Hilfen: Mit %LFN
kann ermittelt werden, ob die aktuelle Windowsversion (ab Windows 95) lange Dateinamen
unterstützt. Dabei wird die Windows-Version abgefragt. Mit SETLFN kann man diese Abfrage
auch bewußt steuern. So mag es aus Kompatibilitätsgründen in bestimmten Situationen
notwendig sein mit SETLFN 0 die Verwendung langer Dateinamen zu unterbinden. Die
Funktionen @LONGNAME$ und @SHORTNAME$ ermöglichen die Umwandlung von
kurzen Dateinamen in langen Dateinamen und umgekehrt.
HINWEIS: Da die 32-Bit-Version von PROFAN² Windows 95 (oder höher) vorraussetzt,
werden hier die langen Dateinamen durchgehend unterstützt. SETLFN erzeugt zwar keinen
Fehler, bleibt aber wirkungslos. Die Systemvariable %LFN liefert immer das Ergebnis 1
zurück.
Seite 87
RGH-PROFAN²
22 - Die Verbindung zur Außenwelt
Es gibt eine Welt außerhalb des Computers! PROFAN² bietet zahlreiche Möglichkeiten, mit
dieser Welt Kontakt aufzunehmen.
22.1 Drucken mit PROFAN²
PROFAN² unterstützt selbstverständlich auch direkt den Drucker. Unter Windows ist Drucken
immer seitenorientiert. Ich teile also Windows mit, wenn eine neue Seite beginnen soll,
erstelle diese Seite und gebe dann die Anweisung, diese Seite zu drucken.
Mit dem Befehl STARTPRINT beginne ich eine neue Seite. Alle danach folgenden Ausgaben
gehen nicht auf den Bildschirm, sondern auf den Drucker. Einige Befehle sind während des
Druckens nicht erlaubt. Das betrifft insbesondere einige Befehle, die sich mit BitmapGrafiken befassen, wie z.B. MLOADBMP, MCOPYBMP, COPYSIZEDBMP oder COPYBMP.
Ebenso ist der FILL-Befehl nicht gestattet. Alle anderen Befehle zur Text- oder
Grafikausgabe funktionieren wie gewohnt. Ab Version 3.3 lassen sich mit LOADBMP und
LOADSIZEDBMP Bitmapgrafiken direkt in ausgezeichneter Qualität auf den Drucker
ausgeben. Der einzige Unterschied: Während der Bildschirm max. 640 Pixel breit und 480
Pixel hoch ist, hat die Druckseite eine Breite von 640 Einheiten und eine Höhe von 960
Einheiten. Ebenso wie auf dem Bildschirm lassen sich die Truetype-Fonts beliebig skalieren
und drehen! Innerhalb eines Druckauftrages zwischen STARTPRINT und ENDPRINT wird
mit NEXTPAGE eine neue Seite begonnen. Ist die Seite fertig, wird sie mit ENDPRINT
ausgegeben. Beispiel:
StartPrint
Rectangle 100,100 - 550,850
DrawText 150,150,"Testtext"
EndPrint
Eine weitere Druckmöglichkeit besteht durch den Befehl SCREENCOPY. Wird er ohne
Parameter aufgerufen, wird eine Hardcopy des aktuellen Bildschirmes auf den Drucker
ausgegeben. Durch Parameter kann aber auch der Bereich eingeschränkt werden, der
gedruckt wird:
ScreenCopy
ScreenCopy 20,20 - 400,300
Während SCREENCOPY nur den Client-Bereich des Hauptfensters (incl. der darauf
liegenden Dialoge und Fenster) abbilden kann, kann mi dem Befehl WINCOPY jedes
beliebige Fenster bzw. Fensterelement, dessen Handle bekannt ist, ausgedruckt werden.
Beispiel zum Ausdruck des gesamten Bildschirmes:
WinCopy %DeskTop
22.2 Die serielle Schnittstelle
Set Version 4.0 kann PROFAN² auch über die serielle Schnittstelle kommunizieren. Sei es,
daß ein Modem angesteuert wird, Verbindungen zu anderen Rechnern hergestellt werden
oder Geräte gesteuert bzw. ausgelesen werden.
Seite 88
RGH-PROFAN²
Um eine serielle Schnittstelle zu nutzen, muß sie mit @OpenCom geöffnet werden. Der
Rückgabewert dieser Funktion ist das Handle auf die Schnittstelle. Dieses wird für die
anderen Funktionen benötigt. Beim Öffnen geben sie an, welche Schnittstelle Sie öffnen
wollen und wie groß die Puffer für die Sende- und Empfangsdaten sind. Geben Sie diese
Werte nicht zu klein an, damit keine Daten verloren gehen, während das System mit anderen
Dingen beschäftigt ist. 1024 Bytes sollten mindestens für jeden Puffer vorgesehen werden:
LET h% = @OpenCom("COM2",1024,1024)
Die Schnittstelle wird mit Standardwerten geöffnet. Ist der Rückgabewert h% negativ, ist ein
Fehler aufgetreten. Um die Schnittstellenparameter einzustellen, muß die Funktion
@SetCom aufgerufen werden. Sie hat nur einen Parameter: Einen String, der dem
ensprechenden DOS-Parameter für den MODE-Befehl entspricht:
LET e% = @SetCom("COM2:9600,N,8,1")
Hier wird COM2 auf 9600 Baud, keine Parität, 8 Datenbits, 1 Stopbit eingestellt. Ist ein
Fehler aufgetreten, dann wird das Ergebnis e% negativ. Die Funktion muß nach @OpenCom
aufgerufen werden! Sie kann auch mitten im Betrieb aufgerufen werden, um die Parameter
zu ändern. Dabei ist jedoch zu berücksichtigen, daß Sende- und Empfangspuffer geleert
werden. Es sollte vom Programm also sichergestellt werden, daß keine Daten verloren
gehen. Weitere Einstellungsmöglichkeiten ergeben sich mit @SETCOMEXT.
Gelesen werden die Daten, die an der seriellen Schnittstelle anliegen mit @READCOM$
und gesendet mit @WriteCom. Mit @COMERROR sollte jedes Lesen und Schreiben
anschließend überprüft werden und nach einem Fehler die Schnittstelle wieder freigegeben
werden. Vergessen Sie nicht, die Schnittstelle anschließend mit @CloseCom zu schließen.
Das folgende Beispielprogramm stellt ein minimalistisches Terminal dar, daß mit "§"
(<Shift><3>) beendet wird:
Declare a$, f%, ende%
Proc GetComInput
'--------------Parameters id%
Declare x$
Let x$=@readcom$(id%,1)
@comerror(id%)
Print x$;
WhileNot @equ$(x$,"")
Let x$=@readcom$(id%,1)
@comerror(id%)
Print x$;
EndWhile
EndProc
Window 0,0-%MaxX,%MaxY
Seite 89
RGH-PROFAN²
Let f% = @OpenCom("COM2",1024,1024)
@SetCom("COM2:2400,N,8,1")
@WriteCom(f%,"ATZ\n") ' Modem initialisieren
@ComError(f%)
GetComInput f%
' Antwort abwarten und anzeigen
Let ende% = 0
WhileNot ende%
Let a$ = @inkey$()
' Tastatur abfragen
If @Equ$(a$,"§")
' Ende mit SHIFT-3
Let ende%=1
Else
IfNot @equ$(a$,"") ' Wurde ein Zeichen eingegeben,
' dann ans Modem damit
@WriteCom(f%,a$)
Endif
GetComInput f%
' empfangene Zeichen lesen
Endif
Wend
@CloseCom(f%)
End
Die Prozedur @GETCOMINPUT liest solange Zeichen aus der seriellen Schnittstelle,
solange welche anliegen. Wenn man sicher ist, das nie mehr als 255 Zeichen anliegen,
könnte man die Prozedur auch auf zwei Zeilen reduzieren:
Let X$ = @ReadCom$(f%,255)
Case @Len(X$):Print X$
22.3 I/O-Ports
HINWEIS: Unter Windows NT ist die direkte Kommunikation mit den Ports nicht mehr
erlaubt!
Speziell für Hardware-Erweiterungen ist es interessant direkt über die I/O-Ports des PC
Kontakt mit der Umwelt aufzunehmen. Auch manche Hardwarekomponenten des PC können
über die I/O-Ports direkt angesprochen werden, indem entsprechende Werte in die Register
geschrieben werden. Hierfür bietet PROFAN² spezielle Befehle und Funktionen an:
Mit OUTP wird ein 16-Bit Wert an die angegebene I/O-Adresse ausgegeben. Da hier ein 16
Bit-breiter Wert an die Außenwelt gegeben wird, werden zwei benachbarte Port-Adressen
benutzt: Die im Befehl angegebene und die darauffolgende Adresse. Wenn gezielt nur ein 8Bit Wert ausgegeben werden soll, ist der Befehl OUTPB zu verwenden, wobei das
zusätzliche B für Byte steht.
Zum Lesen der Ports gibt es zwei entsprechende Funktionen, nämlich @INP und @INPB.
Diese Befehle und Funktionen sollte man nur verwenden, wenn man genau weiß was man
tut. Zum einen können einige Adressen selbst beim Lesen Windows zum Stillstand bringen
und zum anderen kann nicht 100%ig ausgerschlossen werden, das durch bestimmte OUTBefehle die Hardware in Mitleidenschaft gezogen wird. So ist es zum Beispiel möglich, durch
direktes Beschreiben der Register der Videokarte die Videokarte und/oder den Monitor zu
beschädigen.
Seite 90
RGH-PROFAN²
23 - Fertige Dialoge
PROFAN² unterstützt zwar bereits seit Version 3.0 auch selbstdefinierte Dialoge, bietet aber
trotzdem eine ganze Reihe von fertigen Standarddialogen an, die manche
Programmierarbeit ersparen:
23.1 MessageBox
Da ist zunächst einmal die Messagebox zur Ausgabe einer einfachen Meldung bzw. Frage
auf den Bildschirm. Eine Messagebox hat drei Parameter: Der erste Parameter ist der Text
der Meldung oder Frage, der zweite Parameter ist die Überschrift und der dritte Parameter ist
eine Zahl und kennzeichnet die Fensterart, das Icon und die Anzahl der Buttons. Der Wert
setzt sich zusammen aus BUTTONS + ICON + DEFAULT + FENSTERART:
Werte für BUTTON:
0
1
2
3
4
5
- OK
- OK Abbrechen
- Abbrechen Wiederholen Ignorieren
- Ja Nein Abbrechen
- Ja Nein
- Wiederholen Abbrechen
Werte für ICON:
0
16
32
49
64
- Kein Icon
- STOP
- "?"
- "!"
- "i"
Werte für DEFAULT-Knopf:
0
256
512
- 1. Knopf
- 2. Knopf
- 3. Knopf
Werte für FENSTERART:
0
4096
- "normales" Fenster.
- nicht verschiebbares "Fehler"-Fenster.
Das Ergebnis der Messagebox-Funktion ist eine Zahl, die für den gewählten Button steht:
1
2
3
4
5
6
7
- OK
- Abbrechen (Cancel)
- Abbrechen (Abort)
- Wiederholen
- Ignorieren
- Ja
- Nein
Seite 91
RGH-PROFAN²
Ein kleines Beispiel:
Declare Ende%
Declare Knopf%
'Ende-Schalter
'Enthält Button-Wert
Let Ende% = 0
WhileNot Ende%
Let Knopf% = @MessageBox \
("Willst Du schon aufhören?",\
"Ernstgemeinte Frage",292)
Case @Equ(Knopf%,6): Let Ende% = 1
Wend
Die 292 setzen sich wie folgt zusammen: Das Icon in der Messagebox ist ein Fragezeichen
(=32), es soll eine "Ja/Nein" Messagebox sein (=4) und der zweite Button (der "Nein"-Knopf)
soll vorgewählt sein (=256). Diese Werte addiert ergeben 292. Die 6 steht schließlich für den
"Ja"-Knopf.
Aus Gründen der Kompatibilität zu PROFAN 1.x gibt es auch noch den MessageBox-Befehl.
Mit ihm sähe obiges Programm wie folgt aus:
Declare Ende%
Declare Knopf%
'Ende-Schalter
'Enthält Button-Wert
Let Ende% = 0
WhileNot Ende%
MessageBox "Willst Du schon aufhören?",\
"Ernstgemeinte Frage",292
Let Knopf% = %Button
Case @Equ(Knopf%,6): Let Ende% = 1
Wend
End
Diese Form sollte jedoch nicht verwandt werden, da in künftigen Versionen von PROFAN²
dieser Befehl nicht mehr zur Verfügung stehen wird.
23.2 InputBox und EditBox
Ein weiterer Dialog ist die InputBox. Sie ermöglicht die Eingabe eines beliebigen Wertes. Die
Funktion hat drei Parameter: Der erste Parameter ist der "Prompt", also die Frage bzw. Hilfe
zur Eingabe. Der zweite Parameter ist die Überschrift des Dialoges und der dritte Parameter
ein Vorgabewert. Dieser Vorgabewert steht schon beim Aufruf in der Inputbox und kann
übernommen oder überschrieben werden. Ein Beispiel:
Declare Text$
Let Text$ = "Mannheim"
Let Text$ = @Input$("Wohin möchten Sie reisen?",\
"REISEZIEL",Text$)
Print Text$
WaitKey
End
Seite 92
RGH-PROFAN²
Ab PROFAN² 2.5 kann sowohl die Vorgabe als auch das Ergebnis numerisch sein. Die
Funktion kann so zur Eingabe von Strings und numerischen Werten verwandt werden.
Beispiel:
Let Z&=@Input$("Neuer Wert:","Test",Z&)
Neu in PROFAN² 3.2 war die mehrzeilige Inputbox, die EditBox, die die Editierung
kompletter Texte bis 30 kB erlaubt. Der zu editierende Text ist in die Listboxliste einzulesen.
Dann wird die Funktion @EditBox aufgerufen, um den Text zu editieren. Anschließend kann
er wieder aus der Listboxliste in eine Datei geschrieben werden. Wenn die EditBox mit "OK"
verlassen wurde, gibt die Funktion den Wert 1 zurück. Im Beispiel wird die Datei
"TEST.PRF" editiert:
Declare Text$,A%
ClearList
Assign #1,"C:\PROFAN33\TEST.PRF"
Reset #1
WhileNot @Eof(#1)
Input #1,Text$
AddString Text$
Wend
Close #1
If @EditBox("Editiere TEST.PRF",2)
Rewrite #1
Let A% = 0
WhileNot @Gt(A%,%GetCount)
Print #1,@ListBoxItem$(A%)
Inc A%
Wend
Close #1
EndIf
End
23.3 ListBox
Der mächtigste Dialog von PROFAN² ist die ListBox. Dazu gibt es ein eigenes String-Feld,
das bis zu 32000 Einträge (16-Bit-Version: 16000 Einträge) haben kann. Diese Strings
werden dann in der ListBox angezeigt und einer kann dann vom Anwender ausgewählt
werden. Um diese ListBox-Liste zu leeren gibt es den Befehl CLEARLIST. Gefüllt werden
kann diese Liste mit den Befehlen ADDSTRING und/oder ADDFILES und/oder
ADDWINDOWS. ADDSTRING fügt einen Eintrag, der als Parameter angegeben wird, zur
Liste hinzu. Mit ADDFILES werden die Dateinamen eines Verzeichnisses der Liste
hinzugefügt, wobei Verzeichnisnamen in eckige Klammern gestellt werden. ADDFILES
verlangt als Parameter eine Dateimaske und den Pfad. Wird der Pfad weggelassen, wird das
aktuelle Verzeichnis gelesen. ADDWINDOWS liest die Titel der z.Zt. aktiven Programme,
deren Titel mit dem als Parameter verwandten String beginnt, ein. Sollen alle Fenstertitel
gelistet werden, ist der Leerstring als Parameterzu verwenden.
Angezeigt wird der Dialog mit der @LISTBOX$-Funktion, die zwei Parameter hat: Der erste
Parameter ist die Überschrift und der zweite Parameter gibt an, in welcher Form die ListBox
angezeigt werden soll:
1
2
3
4
5
6
7
8
- groß - unsortiert - Systemschrift
- groß - unsortiert - Courier 10
- groß - sortiert - Systemschrift
- groß - sortiert - Courier 10
- klein - unsortiert - Systemschrift
- klein - unsortiert - Courier 10
- klein - sortiert - Systemschrift
- klein - sortiert - Courier 10
Seite 93
RGH-PROFAN²
Aus Gründen der Kompatibilität zu PROFAN² 2.x ist auch noch der Parameter 0 erlaubt. Er
hat die gleiche Wirkung wie 7!
Die große (unsortierte) ListBox eignet sich insbesondere zur Darstellung von Texten. Diese
werden eingelesen und dann angezeigt. Beispiele für ListBoxen:
Declare Text$, Wahl$
'Eine kleine ListBox mit verschiedenen Strings
ClearList
AddString
AddString
AddString
AddString
Let Wahl$
Print "Du
"Rot"
"Blau"
"Grün"
"Schwarz"
= @ListBox$("Wähle ein Farbe:",7)
hast ";Wahl$;" gewählt."
'Eine kleine ListBox mit Dateiliste
ClearList
AddFiles "C:\WIN31\*.*"
Let Wahl$ = @ListBox$("Wähle eine Datei:",8)
Print "Du hast aus ";%GetCount,\
" Einträgen ";Wahl$;" ausgewählt."
'Eine große Box zur Anzeige eines Textes
ClearList
Assign #1,"C:\WIN31\WIN.INI"
Reset #1
WhileNot @Eof(#1)
Input #1,Text$
AddString Text$
Wend
Close #1
@ListBox$("WIN.INI",1)
End
Mit %GETCOUNT wird die Nummer des letzten Eintrags in der ListBox-Liste ermittelt.
ACHTUNG: Da der erste Eintrag die Nummer 0 hat, ist die tatsächliche Anzahl der Einträge
um 1 höher! Zusätzlich besteht die Möglichkeit, mit der Funktion @LISTBOXITEM$ einen
speziellen Eintrag in der ListBox zu ermitteln. Mit dem Befehl LISTBOXITEM$ kann ein
spezieller Eintrag ersetzt werden. %GETCURSEL gibt die Position des ausgewählten
Eintrages in der ListBox an. Bei einer sortierten ListBox entspricht dies nicht der Position des
Eintrages in der ListBoxListe!
Seite 94
RGH-PROFAN²
23.4 LOAD- und SAVE-Dialoge
Am häufigsten gebraucht werden Dialoge zum Laden und Speichern von Dateien. Daher gibt
es diese in PROFAN² schon fix und fertig. Gewiß, es wäre auch möglich, solche Dialoge
vermittels der Listbox abzuwicklen, aber so ist es einfacher:
Declare Name$
Let Name$ = @LoadFile$("Lade ein Bild","*.BMP")
LoadSizedBmp Name$,0,0-100,100
Let Name$ = @SaveFile$("Speichere das Bild","NEU.BMP")
If NEqu$(Name$,"")
SaveBmp Name$,0,0-100,100
EndIf
WaitInput
End
Der Name "NEU.BMP" wird für das Speichern vorgeschlagen, kann aber jederzeit im Dialog
geändert werden. Wenn das Ergebnis eines SaveFile-Dialoges der Leerstring ist wurde der
Dialog mit "Abbruch" beendet. Probieren Sie bitte - wie immer - alle Beispiele aus.
In der 32-Bit-Version werden die Systemdialoge zum Laden und Speichern verwandt. Diese
erlauben den Einsatz mehrerer Dateifilter. Will man dieses Feature nutzen, kann man
mehrere Dateifilter, die jeweils aus Beschreibunng und ndung bestehen, kombinieren.
Wollten wir in unserem Beispiel neben *.BMP-Dateien auch *.RLE-Dateien laden, könnte die
Zeile wie folgt aussehen:
Let Name$ = @LoadFile$("Lade ein Bild", \
"Normal|*.BMP|komprimiert|*.RLE")
Der senkrechte Strich wird mit [AltGr]+[<] erreicht.
Außerdem gibt es noch den Verzeichniswechsel-Dialog. Er ähnelt dem SAVE-Dialog mit
dem Unterschied, daß kein Dateiname eingegeben werden kann. Der Rückgabewert ist der
gewählte Pfad:
Let Pfad$ = @ChooseDir$("Verzeichnis wählen:")
ChDir Pfad$
Bitte beachten: Der Dialog selbst wechselt nicht in den Pfad, sondern er gibt nur einen
vorhandenen und gewählten Pfad zurück. Wird er mit "Abbruch" beendet, ist der
Rückgabestring leer!
Seite 95
RGH-PROFAN²
24 - Selbstdefinierte Dialoge
Ursprünglich kannte PROFAN² nur vordefinierte Dialogboxen, die ohne Aufwand vom
Programmierer eingesetzt werden können und für die meisten einfacheren Programme auch
ausreichend sind: Eingabedialog mit @INPUT$, Listboxen mit @LISTBOX$, Dialoge zum
laden und speichern und zur Auswahl eines Verzeichnisses. Mit nur einer Programmzeile
lassen sich so die gängigsten Dialogboxen auf den Bildschirm zaubern.
All dieses bleibt natürlich bestehen (und wird in künftigen Versionen noch erweitert).
In PROFAN² 3.0 kamen frei definierbare Dialogboxen hinzu, damit der erfahrenere
Programmierer die Möglichkeiten von Windows auch nutzen kann. Mit der PROFAN²Version 4.0 wurden die Dialogelemente für den PROFAN²-Programmierer wesentlich
erweitert und durch den neuen Datentyp 'Bereich' erschließen sich weitgehende
Möglichkeiten durch Nutzung der @SendMessage-Funktion. In Version 4.1 kamen nun auch
noch die Scrollbalken als Dialogelemente dazu. Und seit Version 6.0 können mit
@CONTROL beliebige Dialogelemente genutzt werden.
24.1 Dialoge - Grundlagen
Selbstdefinierte Dialogboxen gibt es in zwei Ausprägungen: Einmal als Dialogbox mit fester
Fenstergröße
(@CREATEDIALOG)
und
zum
zweiten
als
Dialogfenster
(@CREATEWINDOW), dessen Stil mit WINDOWSTYLE eingestellt werden kann. In beiden
Fällen handelt es sich um nichtmodale Fenster, d.h.: Wenn der Anwender außerhalb des
Dialoges etwas anklickt, kann die Anwendung darauf reagieren. Soll der Anwender nichts
anderes machen können, bevor der Dialog abgearbeitet ist muß das Programm (will heißen:
Sie als Programmierer) dafür Sorge tragen, daß nur auf Ereignisse des Dialoges reagiert
wird. Normalerweise wird man für jeden Dialog eine eigene Prozedur schreiben, die erst
dann verlassen wird, wenn der Dialog beendet ist:
PROC Dialog
Declare hD%, hB%, OK%, <...>
'Dialogfenster erzeugen
Let hD% = @CreateDialog(%HWnd,"Dialogfenster",10,10,100,100)
'Einen Button mit OK erzeugen
Let hB% = @CreateButton(hD%,"&OK",50,50,20,20)
<... hier werden die anderen Elemente definiert ...>
Let OK% = 0
WhileNot Ok%
WaitInput
If @GetFocus(hB%) 'OK wurde angeklickt
Let Ok% = 1
ElseIf <...>
<... andere Abfragen und Aktionen ...>
EndIf
EndWhile
'Dialogfenster (incl. Button) entfernen
@DestroyWindow(hD%)
ENDPROC
Die eckigen Klammern <...> stellen Platzhalter für Ihre Erweiterungen dar.
Wie auch bei Menüs kann mit einem & der Hotkey, der unterstrichene Buchstabe markiert
werden. Dieses Fensterobjekt kann dann mit ALT und diesem Buchstaben angewählt
werden.
Seite 96
RGH-PROFAN²
In unserem Beispielprogramm gehört das Dialogfenster zum PROFAN-Hauptfenster
(%HWnd) und sein Handle wird in hD% gespeichert. Die Fensterobjekte des Dialoges
gehören zum Dialogfenster (hd%). Im Beispiel wird ein Button mit der Aufschrift "OK"
erzeugt und sein Handle in hB% gespeichert. Anschließend folgt die in PROFAN übliche
WHILE-Schleife mit dem WAITINPUT. WAITINPUT wartet auf ein Ereignis.
Ein solches Ereignis ist z.B. das Anklicken eines Fensterobjektes oder das <Enter> in einem
Eingabefeld oder Drücken eines über TAB angewählten Buttons mit SPACE ...
Im Beispiel wird dann, wenn das Ereignis den "OK"-Button betrifft, die Variable OK% auf 1
gesetzt und damit die WHILE-Schleife verlassen. Vor Verlassen der Dialog-Prozedur wird
das Dialogfenster entfernt und mit ihm auch der OK-Button, da dieser ja in der
Fensterhierarchie ein dem Dialogfenster untergeordnetes Fenster war.
(Man spricht hier auch von "Eltern- " und "Kindfenster", bzw. "Parentwindow" und
"Childwindow".)
Einzelne Dialogelemente (und Fenster) können mit ENABLEWINDOW deaktiviert (gesperrt)
und wieder aktiviert werden. Ihre Position und Größe kann nachträglich mit dem Befehl
SETWINDOWPOS verändert werden.
Normalerweise wird in Dialogfenstern die in der Systemsteuerung eingestellte Systemschrift
verwandt. Es gibt jedoch auch die Möglichkeit, die ganze Vielfalt der Schriften von Windows
zu nutzen ... mit einer Einschränkung: Außer der Systemschrift ist nur eine weitere Schrift in
einem Dialogfenster möglich. Um die Schrift einzustellen, muß diese wie gewohnt mit
USEFONT eingestellt werden. Mit der Befehl SETDIALOGFONT 1 weisen Sie PROFAN² an,
für die nachfolgenden @CREATE-Funktionen den eingestellten Font zu benutzen. Um
wieder die Systemschrift zu verwenden geben Sie als Parameter bei SETDIALOGFONT den
Wert 0 an. Um die Schrift eines Dialogelementes nach dem Erzeugen zu ändern, kann mit
@SENDMESSAGE die Message wm_SetFont an das Element gesandt werden.
HINWEIS: Es ist natürlich auch möglich, die einzelnen Dialogelemente direkt auf das
Hauptfenster eines PROFAN²-Programmes (%HWnd) anzubringen. Da dieses Fenster aber
intern nicht den Stil eines Dialogfensters hat, reagieren manche Dialogelemente etwas
anders, als in einem Dialogfenster. So funktioniert z.B. das Wechseln von einem Element
zum nächsten mit <TAB> nicht. Auch das Anwählen eines Buttons oder anderen
Steuerelementes über ALT und dem unterstrichenen Buchstaben funktioniert nicht. Das
Drücken eines Knopfes löst zwei Ereignisse aus: beim Drücken und beim Loslassen. (Im
normalen Dialog-Fenster wird nur ein Ereignis beim Loslassen erzeugt.)
Seit Version 5.0 ist es jedoch möglich, auch dem Hauptfenster mit WINDOWSTYLE den Stil
eines Dialogfensters zuzuweisen. Dann reagiert es nahezu genau wie ein Dialogfenster.
Beachten Sie bitte, daß damit auch Einschränkungen verbunden sind, da ein Dialogfenster
kaum auf Tastaturereignisse reagiert, die über die oben erwähnten Hotkeys bzw. F1
hinausgehen.
TIP: Um herauszubekommen, welche Aktion nun welches Ereignis auslöst und wie sich das
in den entsprechenden Systemvariablen niederschlägt, füge ich in der Testphase folgende
Zeile hinter dem WAITINPUT des entsprechenden Fensters/Dialoges ein:
PRINT %MenuItem,%Key,%ScanKey,%GetFocus,%MoseKey,%MouseX,%MouseY
So erhalte ich einen Überblick, was durch was ausgelöst wird und kann mein Programm
entsprechend darauf abstellen.
Seite 97
RGH-PROFAN²
24.2 Buttons, Checkboxen und Radiobuttons
Diese drei Typen von Dialogelementen sind hier zusammen aufgeführt, weil sie einer Klasse
von Dialogelementen angehören: Sie werden mit denselben Befehlen und Funktionen
behandelt und verstehen dieselben Messages!
Da gibt es zunächst den ganz normalen Button (neudeutsch für 'Druck-Knopf'). Wenn er
gedrückt und losgelassen wird löst er ein Ereignis aus. Mit %GETFOCUS kann ermittelt
werden, welches Dialogelement das Ereignis auslöste. Der Button hat einen Text, der mit
SETTEXT auch noch nachträglich geändert werden kann. Wenn ein Buchstabe des Textes
ein vorangestelltes & hat, wird er auf dem Button unterstrichen dargestellt und der Button
kann im Dialog bzw. Dialogfenster mit ALT und dem Buchstaben angewählt werden.
@GETTEXT$ ermittelt den Text eines Buttons.
Eine Sonderform des Buttons ist der Default-Button, d.h. der standardmäßig aktivierte
Button.
Eine CheckBox ist ein kleines Kästchen, das angekreuzt sein kann oder auch nicht. Nach
dem Erzeugen ist es zunächst nicht angekreuzt. Mit dem Befehl SETCHECK kann der
Zustand der Checkbox eingestellt werden und mit der Funktion @GETCHECK kann er vom
Programm abgefragt werden. Der Text wird links neben dem Kästchen dargestellt.
Ansonsten gilt für ihn das gleiche, wie für den Text eines Buttons.
Ein RadioButton ist ein rundes Kästchen. Mehrere Radiobuttons sind in der Regel in einer
Gruppe zusammengefaßt und es kann immer nur einer markiert sein. Auch hier wird der
Zustand mit SETCHECK eingestellt und mit @GETCHECK ausgelesen. Sollen mehrere
Gruppen von Radiobuttons in einem Dialogfenster Verwendung finden, sind sie mit
CREATEGROUPBOX zu gruppieren. Der Text eines Radiobuttons wird rechts neben dem
Knopf dargestellt
Neben den allgemeinen Messages wm_SetText und wm_SetFont sind im Zusammenhang
mit Buttons und Checkboxen die Button-Messages interessant. So kann zum Beispiel mit
bm_GetState herausbekommen werden, ob ein Button gerade gedrückt ist oder nicht. Die
Messages werden mit @SendMessage an das betreffende Steuerelement gesandt.
TIP: Wenn PROFAN² auch (noch) keine Buttons mit Bitmaps unterstützt, so können doch
Buttons mit Symbolen unter Verwendung der Schrift "WingDings" erzeugt werden. Diese
enthält nahezu alle gebräuchlichen Symbole. Vor dem entsprechenden USEFONT ist mit
CHARSET 2 der Symbolzeichensatz einzustellen:
<...>
CharSet 2
'Zeichensatz wählen
UseFont "WingDings",16,0,0,0,0 'Schrift wählen
SetDialogFont 1
'Font für Dialog nutzen
CreateButton(%Hwnd,"0",10,10,16,16)
<...>
Seite 98
RGH-PROFAN²
24.3 GroupBoxen, Texte und Icons
Die hier beschriebenen drei Dialogemelemente gehören einer Klasse an, da sie eines
gemeinsam haben: Sie sind statisch! Sie werden einmal erzeugt und bleiben dann
unverändert. Lediglich der Text läßt sich mit @SETTEXT verändern. Beim Anklicken aber
passiert gar nichts, das Element bleibt unverändert. Es wird zwar ein Ereignis erzeugt,
nämlich der Mausklick, aber nichts weiter. Keine Systemvariable weiß, ob ein statisches
Objekt angeklickt wurde. Genausogut hätte man auf den Dialoghintergrund klicken können.
Lediglich aufgrund der Mausposition beim Anklicken kann das Programm feststellen, daß auf
eine bestimmte Stelle geklickt wurde.
Ein wichtiges Element im Zusammenhang mit den RadioButtons ist die GroupBox. Sie stellt
einen rechteckigen Rahmen dar, der auch links oben einen Text enthalten kann. Wird in
einem Dialog mir RadioButtons keine GroupBox verwandt, gehören alle RadioButtons des
Dialoges einer Gruppe an. Wird einer angeschaltet (markiert), gehen alle anderen aus. Will
man mehrere Gruppen von Radiobuttons bilden, muß man erst die erste Groupbox mit
@CREATEGROUPBOX
erzeugen,
dann
die
entsprechen
Radiobuttons
mit
@CREATERADIOBUTTON, dann die zweite Groupbox und ihre Radionbuttons und so
weiter. Natürlich kann man Groupboxen auch ohne Radiobuttons zur Verschönerung des
Dialoges verwenden.
TIP: Wenn man keinen Text für die Groupbox angibt, erhält man ein schlichtes Rechteck.
Linien lassen sich erzeugen, indem man als Ausdehnung der GroupBox in einer Richtung 0
angibt.
Ein weiteres Dialogelement sind Icons. Alle in PROFAN² vorhandenen Icons können mit
@CREATEICON in einem Dialog plaziert werden. Im Gegensatz zu allen anderen
Dialogelementen kann für ein Icon keine Größe festgelegt werden, da sie vom System
festgelegt ist.
Ein Textfeld dient lediglich zur Anzeige von Text. Sollte es notwendig werden, kann der Text
mit SETTEXT geändert und mit @GETTEXT gelesen werden.
24.4 Editierfelder
Es gibt zwei unterschiedliche Eingabefelder: Einzeilige und mehrzeilige EditBoxen.
Ein einzeilge EditBox kann bis zu 255 Zeichen Text enthalten. Die Funktion @CreateEdit
gibt ein Handle auf das Eingabefeld zurück. Über dieses kann mit @GETTEXT das
Eingegebene ausgelesen werden. Mit SETTEXT ist es möglich den Text im Eingabefeld per
Programm zu bestimmen. Durch Eingabe einer negativen vertikalen Ausdehnung wird die
Paßwortfunktion aktiviert: Eingegebene Zeichen werden als Sterne dargestellt. Die
Paßwortfunktion gibt es nur bei einzeiligen Editierfeldern.
Für längere Texte empfielt sich ein mehrzeiliges Editierfeld. Solange auch hier der Text nicht
über 255 Zeichen lang ist, kann er mit SETTEXT zugewiesen und mit der Funktion
@GETTEXT$ ermittelt werden. Für längere Texte ist hingegen die Funktion
@MOVELISTTOEDIT zu verwenden oder mit der Message wm_SetText der Inhalt einer
Bereichsvariablen an das Editierfeld zu senden. Eine Textdatei kann mit ReadText in eine
Bereichsvariable eingelesen werden. Hierzu ein kleines Beispiel:
DECLARE Edit%,Bereich#
LET Edit% = @CreateMultiEdit(%HWnd,"",10,10,200,200)
DIM Bereich#,@Add(@FileSize("C:\PROFAN40\LIESMICH.TXT"),2)
ReadText Bereich#,"C:\PROFAN40\LIESMICH.TXT"
@SendMessage(Edit%,$000C,0,Bereich#)
WaitInput
End
Seite 99
RGH-PROFAN²
Wird die vertikale Ausdehnung als negativer Wert angegeben, so wird zwar trotzdem der
absolute Wert als Größe genommen, aber gleichzeitig die automatische WortumbruchFunktion aktiviert: Der horizontale Scrollbalken wird nicht angezeigt und ein Wort, das nicht
mehr in eine Zeile paßt wird automatisch in die nächste Zeile gebracht.
Mit der Funktion @GETLINE$ kann der Text eines mehrzeiligen Editierfeldes ausgelesen
werden, wobei die Anzahl der Zeilen mittels @GETLINECOUNT ermittelt wird.
Neben den allgemeinen Messages wm_SetText und wm_SetFont sind im Zusammenhang
mit Editierfeldern die Edit-Messages interessant. Die Messages werden mit @SendMessage
an das betreffende Editierfeld gesandt.
ACHTUNG: Die Funktionen @MOVELISTTOEDIT, @GETLINE$ und @GETLINECOUNT
sind nur auf Editierfelder anzuwenden! Werden Sie auf andere Steuerelemente angewandt
liefern sie unerwartete Ergebnisse und können in einigen Fällen auch Windows oder die
Anwendung zum Absturz bringen!
24.5 ListBoxen
Auch die ListBox gibt es in zwei Varianten: Unsortiert und sortiert. In der unsortierten ListBox
werden die Einträge in der "Reihenfolge des Eingangs" angezeigt, während sie in der
sortierten ListBox alphabetisch sortiert werden.
Die Einträge in der ListBox können mit zahlreichen Funktionen manipuliert werden: Mit
@ADDSTRING und @INSERTSTRING werden der ListBox Einträge hinzugefügt. Mit
@DELETESTRING können Einträge wieder entfernt werden.
Die Anzahl der Einträge in einer Listbox wird mit @GETCOUNT ermittelt. Um
herauszubekommen, welcher Eintrag markiert (ausgewählt) ist, muß die Funktion
@GETCURSEL verwandt werden, welche den Index des gewählten Eintrages zurückgibt.
Den zu einem Index gehörenden String ermittelt die Funktion @GETSTRING$.
Mit @SELECTSTRING kann ein bestimmter Eintrag in der ListBox gesucht und selektiert
werden, d.h. der Markierungsbalken wird auf diesen Eintrag gesetzt.
@MOVELISTTOLIST kann verwandt werden, um den Inhalt der ListBoxListe einer ListBox
hinzuzufügen.
Im Zusammenhang mit ListBoxen sind die ListBox-Messages interessant. So kann zum
Beispiel mit lb_Dir eine Verzeichnis-/Laufwerksliste erzeugt werden oder mit
lb_ResetContent der Inhalt einer ListBox gelöscht werden. Mit lb_SetHorizontalExtend erhält
die Listbox auch horizontale Scrollbalken. Die Messages werden mit @SendMessage an die
betreffende ListBox gesandt.
ACHTUNG: Die hier beschriebenen Funktionen sind nur auf ListBoxen anzuwenden!
Werden Sie auf andere Steuerelemente (z.B. AuswahlBoxen) angewandt liefern sie
unerwartete Ergebnisse und können in einigen Fällen auch Windows oder die Anwendung
zum Absturz bringen! Der Befehl SETTEXT ist keinesfalls auf eine ListBox anzuwenden!
Seite 100
RGH-PROFAN²
24.6 AuswahlBoxen
Eine Auswahlbox ist eine Sonderform der sogenannten "Combobox": Durch Anklicken des
Pfeiles nach unten kann aus einer Liste von Auswahlmöglichkeiten eine Zeile ausgewählt
werden. Eine Eingabe von Zeilen ist nicht möglich. Eine Auswahlbox ist in PROFAN² immer
alphabetisch sortiert.
Mit der Funktion @ADDCHOICE kann der Auswahlbox ein Eintrag hinzugefügt werden. Mit
@MOVELISTTOCHOICE wird die komplette ListBox-Liste, die z.B. zuvor mit ADDFONTS,
ADDFILES oder ADDWINDOWS gefüllt wurde, der Auswahlbox hinzugefügt.
Mit @DELETECHOICE kann ein Eintrag aus der Auswahlbox entfernt werden.
Die ausgewählte Zeile kann mit der Funktion @GETTEXT$ ermittelt werden.
Im Zusammenhang mit AuswahlBoxen sind die AuswahlBox-Messages interessant. So kann
zum Beispiel mit cb_Dir eine Verzeichnis-/Laufwerksliste erzeugt werden oder mit
cb_ResetContent der Inhalt einer AuswahlBox gelöscht werden. Mit cb_SetCurSel kann ein
bestimmter Eintrag vorausgewählt werden. Die Messages werden mit @SendMessage an die
betreffende ListBox gesandt.
ACHTUNG: Die hier beschriebenen Funktionen sind nur auf AuswahlBoxen anzuwenden!
Werden Sie auf andere Steuerelemente (z.B. ListBoxen) angewandt liefern sie unerwartete
Ergebnisse und können in einigen Fällen auch Windows oder die Anwendung zum Absturz
bringen! Der Befehl SETTEXT ist keinesfalls auf eine AuswahlBox anzuwenden!
24.7 ScrollBalken
Ein Scrollbalken ist ein vertikaler oder horizontaler Schieberegler, mit dem Werte eingestellt
werden können. Er läßt sich auch sehr gut für eine Fortschrittsanzeige verwenden. Beliebt ist
der vertikale (senkrechte) Scrollbalken auch zur tastaturlosen Eingabe von Zahlenwerten.
Durch Anklicken der äußeren Schaltfelder kann der Regler um eins erhöht bzw. erniedrigt
werden. Der Regler kann mit der gedrückten Maustaste auch direkt positioniert werden.
Anlicken des Scrollbalkens zwischen Regler und äußeren Schaltflächen erhöht oder
erniedrigt den Wert um ein Zehntel des Bereiches.
Standardmäßg hat ein Scrollbalken einen Bereich von 0 bis 100. Mit dem Befehl
SetScrollRange kann der Bereich aber beliebig eingestellt werden. Wichtig ist, daß Anfangsund Endwert nicht mehr als 32767 auseinanderliegen. Mit SetScrollPos kann ein beliebiger
Wert eingestellt werden. Mit der Funktion @GetScrollPos kann der aktuelle Wert ausgelesen
werden.
ACHTUNG: Die hier beschriebenen Funktionen sind nur auf Scrollbalken anzuwenden!
Werden Sie auf andere Steuerelemente angewandt liefern sie unerwartete Ergebnisse und
können in einigen Fällen auch Windows oder die Anwendung zum Absturz bringen! Der
Befehl SETTEXT ist keinesfalls auf einen Scrollbalken anzuwenden!
24.8 Beliebige Dialogelemente
Es gibt externe DLLs die eigene Dialogelemente enthalten und auch in Windows gibt es
Dialogelemente die PROFAN² noch nicht unterstützt. Um diese zu verwenden wurde die
Funktion @CONTROL geschaffen, die ein beliebiges Dialogelement anzeigen kann, dessen
Klassenname registriert und bekannt ist. DLLs, die neue Dialogelemente beinhalten,
enthalten in der Regel auch Routinen, um diese innerhalb von Wondws zu initialisieren und
registrieren. Beispiel:
DEF GridInit(1) *"GRIDDY.DLL","GridInit","%","%"
...
Seite 101
RGH-PROFAN²
Let hGridDLL% = @UseDLL("GRIDDY.DLL")
Let hGrid% = @GridInit(%Hinstance)
Let Style& = $50810000
Let hGridControl% = \
@Control("griddy","x",Style&,15,15,150,150,\
%Hwnd,100,%Hinstance)
...
FreeDLL(hGridDLL%)
In diesem Beispiel wird GRIDDY.DLL, eine von GFA-BASIC her bekannte DLL zum
Anzeigen eines Tabellen-Controls, verwandt. Auch die bereits in PROFAN bekannten
Dialogelemente lassen sich mit @CONTROL anzeigen und dabei Stile verwenden, die
PROFAN² direkt nicht unterstützt. Folgendes Beispiel zeigt den Einsatz von @Control in
definierten Funktionen, um Text mittig oder rechtsbündig anzuzeigen:
' Beispiel, das zeigt, wie mittels der @Control-Funktion
' Text zentriert und rechtsbündig angezeigt werden kann!
' Definieren der Funktionen (macht die Sache einfacher)
DEF @CreateTextM(6) \
@control("STATIC",@$(2),$50000001,@%(3),@%(4), \
@%(5),@%(6),@%(1),100, %HInstance)
DEF @CreateTextR(6) \
@control("STATIC",@$(2),$50000002,@%(3),@%(4), \
@%(5),@%(6),@%(1),101, %HInstance)
' Das Programm
declare textr%, textm%, textl%
cls
let textl% = @CreateText (%Hwnd,"Bitte eine",0,20,630,20)
let textm% = @CreateTextM(%Hwnd,"Taste",
0,40,630,20)
let textr% = @CreateTextR(%Hwnd,"drücken!", 0,60,630,20)
waitinput
settext textl%,"Links"
settext textm%,"Mitte"
settext textr%,"Rechts"
waitinput
end
Sehr interessant ist auch die Verwendung der PROFAN²-eigenen Fensterklassen mit der
@CONTROL-Funktion, weil man dann zwar die Fenster mit beliebigen Stilkonstanten
versehen kann, aber dennoch die Fensterprozeduren von PROFAN² greifen. Damit können
in diesen Fenstern dann Tastatur-, Maus-, Menü- und sonstige Anfragen wie gewohnt
behandelt werden. Die Fensterklasse des Hauptfensters in PROFAN² ist "FENSTER", die
des mit @CreateWindow geöffneten Fensters ist "DIALOG".
Seite 102
RGH-PROFAN²
25 - Kommunikation mit anderen Fenstern - Messages - DDE
Das PROFAN²-Hauptfenster ist ja nicht das einzigste Windowsprogramm im System.
PROFAN² bietet zahlreiche Zugriffsmöglichkeiten auf und Kommunikationsmöglichkeiten mit
anderen Fenstern.
25.1
Einfacher Zugriff über das Handle
Durch den Zugriff auf Fenster über ihr Handle kann ich auch auf andere
Windowsanwendungen Einfluß ausüben. Über die Funktionen @FINDWINDOW und
@GETACTIVEWINDOW kann ich das Handle anderer Fenster herausbekommen. Das
Hintergrundfenster von Windows hat das Handle %DESKTOP.
ACHTUNG:
Bei
32-Bit-Programmen
ist
es
durchaus
denkbar,
daß
mit
@GETACTIVEWINDOW ein aktives Fenster außerhalb der aktuellen Anwendung nicht
ermittelt werden kann, da die Anwendungen hier untereinander deutlich mehr abgeschottet
sind. Hier führt möglicherweise @FINDWINDOW zum Ziel! Im Zweifelsfall gilt hier wie
überall auch: Ausprobieren!
Wenn ich das Handle habe, könnte ich sogar einem fremden Fenster eine Dialogbox
zuordnen oder Messages schicken ... aber das ist jetzt wirklich was für fortgeschrittene
Programmierer. Ein kleines Beispiel, in dem der Windows-Editor geladen und zu einem Icon
verkleinert wird:
<...>
Shell "NOTEPAD.EXE"
'Hierdurch wird der Editor aufgerufen
'und zum aktiven Fenster
Let hE% = @GetActiveWindow()
'Das Handle des Editors wird gespeichert
@ShowWindow(hE%,6)
'Der Editor wird zum Icon
@SetActiveWindow(%HWnd)
'... und das PROFAN-Fenster wieder aktiviert
<...>
Es gibt noch ein weiteres Handle: Wenn ich ein Programm nicht mit SHELL, sondern mit der
Funktion @WINEXEC aufrufe, ist der Rückgabewert das Instanzhandle des Programmes
(oder wenn er kleiner als 32 ist, eine Fehlernummer):
0235810 11 12 14 15 16 19 20 21 -
Zuwenig freier Speicher oder die ausführbare Datei war beschädigt
Datei nicht gefunden.
Pfad nicht gefunden.
Es gab einen Fehler beim gemeinsamen Zugriff bzw. einen Zugriffsfehler im
Netzwerk.
Ungenügender Speicher, um die Anwendung zu starten.
Falsche Windows-Version.
Ungültige .EXE-Datei (Keine Windows-.EXE-Datei oder Fehler im .EXEDarstellungsformat).
Anwendung wurde für anderes Betriebssystem entworfen.
Unbekannter .EXE-Dateityp.
Versuch, im Protected Mode (Standardmodus oder erweiterter 386-Modus) eine
für frühere Windows-Versionen erstellte .EXE-Datei zu laden
Es wurde versucht, eine zweite Instanz einer ausführbaren Datei zu laden, die
mehrfache (nicht Read-Only markierte) Datensegmente enthält.
Es wurde versucht, eine komprimierte ausführbare Datei zu laden. Die Datei muß
dekomprimiert werden, bevor sie geladen werden kann.
Eine der DLLs, die zum Start dieser Anwendung notwendig ist, war fehlerhaft.
Die Anwendung benötigt 32-Bit-Erweiterungen (WIN32S).
Seite 103
RGH-PROFAN²
Mit der Funktion @GETUSAGE habe ich dann die Möglichkeit, zu prüfen, ob das Programm
noch läuft. So kann ich z.B. sicher gehen, daß eine Aktion erst dann ausgeführt wird, wenn
ein externes Programm abgeschlossen ist. Beispiel:
<...>
Let hN% = @WinExec("NOTEPAD.EXE",1)
'Aufrufen und in Normalgröße zeigen
If @LT(hN%,32)
'Fehler?
MessageBox("Editor konnte nicht gestartet werden", \
"FEHLER:",0)
Else
While @GetUsage(hN%) 'Solange das Programm läuft ...
Wend
'... gehts nicht weiter
EndIf
<...>
25.2
Tastatureingaben simulieren
Ebenso ist es möglich, an ein fremdes Fenster mit @SENDKEY simulierte Tastatureingaben
zu schicken. Mit @SENDSTRING kann man einen kompletten Text an ein anderes Fenster
übermitteln. Dabei wird weitgehend die gleiche Syntax wie z.B. in Visual Basic verwandt
(siehe in der Referenz).
Nur 16 Bit: Hier ist jedoch zu beachten, daß die Zeichen, die nur mit [AltGr] erreicht werden
können, nicht gesandt werden. Häufig kann man dies jedoch mit einem Trick umgehen: Man
kopiert einen String, der diese Zeichen enthält (z.B. @ \ [ ]), in die Zwischenablage und
sendet dann an das Zielfenster die Botschaft wm_Paste, um die Zwischenablage einzufügen.
Ein ausführliches Beispiel hierfür ist für die 16-Bit-Version WRITE.PRF im BeispielVerzeichnis.
ACHTUNG: Beim Senden von Tastatureingaben können die Ergebnisse bei der 16- und 32Bit-Version von PROFAN² unterschiedlich sein, insbesondere, wenn ein 32-Bit-Programm
Tastatureingaben an ein 16-Bit-Programm schickt bzw. umgekehrt.
25.3
Messages versenden
Beim Versenden von Messages an andere Fenster sollte man genau wissen, was man tut, da
es hier möglich ist Windows zum Absturz zu bringen. Hier nur ein kleines Beispiel, mit dem
man ein fremdes Fenster schließen kann:
<...>
@SendMessage(hE%,$0010,0,0)
'Das Fenster mit dem Handle hE% wird geschlossen.
<...>
Die Benutzung der Funktion @SendMessage ist nur erfahrenen Programmierern anzuraten.
Wie ehedem mit PEEK und POKE kann man zwar sehr viel erreichen, aber ein kleiner Irrtum
oder Fehler kann leicht den Rechner zum Absturz bringen! ACHTUNG: Einige Messages
nutzen in der 32-Bit-Version die Parameter anders als die 16-Bit-Version. Erfahrende
Programmierer werden sich in der entsprechenden Fachliteratur informieren.
Seite 104
RGH-PROFAN²
Um in Erfahrung zu bringen, welche Message was bewirkt, hilft das Studium der
entsprechenden Literatur für Windowsprogrammierer. Da dort häufig nur die von Microsoft
geprägten Namen der Messages genannt werden, gibt es im Anhang eine Liste, die eine
Zuordnung der Namen zu ihrem Wert erlaubt. Dort finden Sie z.B. die Zuordnung "wm_Close
= $0010". Für einige für den PROFAN²-Programmierer interessanten Messages - besonders
im Bereich der selbstdefinierten Dialoge - finden Sie dort auch weitergehende Hinweise.
WICHTIG: Messages, die Zeiger auf Strings und/oder Datenbereiche nutzen oder
zurückliefern, sind mit besonderer Vorsicht zu verwenden, da bei fehlerhafter
Dimensionierung oder Bestückung des Bereiches Windows zum Absturz gebracht werden
kann! (Allgemeine Schutzverletzung ...)
25.4
Fernsteuerung per DDE
DDE steht für dynamischer Datenaustausch. Mittels DDE können Programme miteinander
kommunizieren. Durch OLE hat DDE für den Datenaustausch von Programmen
untereinander mittlerweile etwas an Bedeutung verloren, aber wenn es darum geht, andere
Programme "fernzusteuern", hat DDE nach wie vor seine Berechtigung.
Das meist gebrauchte Beispiel hierfür ist das Anlegen von Programmgruppen und Icons in
denselben. Nahezu alle Windows-Oberflächen reragieren auf die DDE-Befehle für den
Programm-Manager, so auch der Explorer von Windows 95. Natürlich muß man wissen,
welche Themen und welche Befehle die fernzusteuernde Anwendung versteht und auf
welchen Namen sie anspricht. Diese Hinweise findet man - wenn überhaupt - in der
Dokumentation der Anwendung.
Mit DDELINK stellt PROFAN² die Verbindung zum fremden Programm her, mit
DDEEXECUTE werden die Befehle übermittelt und mit DDETERMINATE wird anschließend
die Verbindung beendet. In der Systemvariablen %DDEWIN steht das Handle einer
laufenden DDE-Verbindung bzw. 0, wenn keine aktiv ist.
Für den Programm-Manager sind diese Dinge in dem ausführlich dokumentierten Beispiel
DDE-TEST.PRF dokumentiert.
Begriffserklärung: Handle
In der Referenz ist oftmals vom Handle eines Fensters, eines Fensterobjektes die Rede.
"Handle" ist englisch und heißt übersetzt "Griff". Ein Handle ist also ein Griff, mit dem ich
Zugriff auf ein Objekt bekomme.
Wenn ein Fenster oder Fensterobjekt unter Windows erzeugt wird, weist Windows diesem
eine interne Verwaltungsnummer, eben dieses Handle zu. Dieser Wert ist ein 16-Bit-Wert (0
... 65355). Der Wert als solcher ist völlig uninteressant, wichtig ist nur, daß er während des
Programmlaufs unverändert bleibt und eindeutig das entsprechende Objekt bezeichnet.
Alle @Create-Funktionen, die ein Fensterobjekt oder Fenster erzeugen, haben als Ergebnis
das entsprechende Handle. Fensterobjekte sind z.B. Eingabefelder, Schaltflächen,
Auswahlfelder, etc. Das Handle des Hauptfensters eines PROFAN-Programmes ist in der
Systemvariablen %HWnd abgelegt, das Handle des Hintergrundfensters ist in %DeskTop
Eine zweite Sorte ist das Instanzhandle. Mit diesem erhalte ich Zugriff auf die Instanz eines
Programmes oder einer DLL unabhängig davon, ob es ein Fenster erzeugt oder nicht. Über
dieses Instanzhandle erhalte ich Zugriff auf die Resourcen eines Programmes/einer DLL und
kann ermitteln, ob dieses Programm noch läuft. Die Funktionen @WINEXEC und @USEDLL
haben als Eregebnis das jeweile Instanzhandle.
Seite 105
RGH-PROFAN²
Begriffserklärung: Hierarchie der Fenster/Fensterobjekte
Jedes Fenster/Fensterobjekt gehört immer zu einem übergeordnetem Fenster und wird
automatisch geschlossen, wenn das übergeordnete Fenster geschlossen wird. Selbst das
Hauptfenster
von PROFAN² hat ein übergeordnetes Fenster, nämlich das
Hintergrundfenster von Windows. Wenn Windows geschlossen wird, werden alle anderen
Fenster geschlossen. Wenn man nun ein Fenster erzeugt, muß man ihm sagen, zu welchem
übergeordnetem Fenster es gehört. In PROFAN² ist dies bei allen @CREATE-Funktionen
der erste Parameter.
Seite 106
RGH-PROFAN²
26 - Menüs und Mäuse
Windows ist ein ereignisgesteuertes System. Bedeutende Ereignisse werden durch Menüs
und PopUp-Menüs ausgelöst.
26.1 - Fenster-Menüs
PROFAN² kennt zwei Sorten Menüs. Da ist zunächst das ganz normale Anwendungsmenü,
das Fenster-Menü. Jedes PROFAN²-Programm läßt sich mit einem eigenen Menü
ausstatten. Ein Fenster-Menü besteht aus mehreren Menüpunkten in der Menüzeile. In der
Regel öffnen sich beim Anwählen dieser Menüpunkte PopUp-Menüs mit weiteren Punkten.
Mit dem POPUP-Befehl wird der Menüzeile ein weiterer Menüpunkt hinzugefügt und mit
APPENDMENU werden die einzelnen Punkte dieses PopUp-Menüs angehängt. Um einen
Buchstaben unterstrichen darzustellen, damit man auch die Tastatur benutzen kann, setzt
man das "&" davor. Die Zahl bei AppendMenü ist die Nummer dieses Menüpunktes. Über
diese Nummer kann festgestellt werden, welcher Menüpunkt gewählt wurde. Werte zwischen
100 und 32766 (mit Ausnahme von 255) sind erlaubt.
Mit dem Befehl SEPARATOR kann auch eine Trennlinie zwischen Menüpunkten eingeführt
werden.
Mit SUBPOPUP wird anstelle eines Menüpunktes ein weiteres Untermenü angehängt, das
mit ENDSUB endet. Die maximale Verschachtelungstiefe von Menüs ist 10.
Mit @MENUITEM wird abgefragt, ob der entsprechende Menüpunkt angewählt wurde. Der
gewählte Menüpunkt ist auch in der Systemvariablen %MENUITEM gespeichert.
Probieren Sie folgendes Beispiel aus, und Ihnen wird klar, was ich so umständlich zu
erklären suche:
Declare Ende% PopUp "&Datei"
AppendMenu 101,"&Laden"
AppendMenu 102,"&Speichern"
AppendMenu 103,"Speichern &als"
Separator
AppendMenu 109,"&Ende"
PopUp "&Bearbeiten"
AppendMenu 111,"&Ausschneiden"
AppendMenu 112,"&Kopieren"
SubPopUp "&Schrift"
AppendMenu 113,"&Arial"
AppendMenu 114,"&Courier"
EndSub
PopUp "&Suchen"
AppendMenu 121,"&Ersetzen"
AppendMenu 122,"&Suchen"
AppendMenuBar 130,"&Info"
PROC Info
@MessageBox("Testprogramm","Info",64)
ENDPROC
PROC Ueber
@MessageBox("Ihr Copyright","Über ...",48)
ENDPROC
PROC WasAnderes
Print "Gewählter Menüpunkt ";%MenuItem
ENDPROC
Let Ende% = 0
Seite 107
RGH-PROFAN²
WhileNot Ende%
WaitInput
If @MenuItem(109)
Let Ende% = 1
ElseIf @MenuItem(130)
Info
ElseIf @MenuItem(254)
Ueber
Else
WasAnderes
EndIf
Wend
End
Dieses Beispiel zeigt, wie die Grundstruktur eines PROFAN²-Programmes mit Menü sein
kann. Zwei Besonderheiten: Mit APPENDMENUBAR wird der Menüzeile ein Menüpunkt
hinzugefügt, der keine weiteren Menüpunkte hat. Beim Anwählen dieses Punktes wird kein
PopUp-Menü geöffnet, sondern sofort eine Aktion ausgeführt. Die zweite Besonderheit ist der
Wert 254. Hier handelt es sich um die Anwahl des Copyright-Zeichens, dem vordersten
Menüpunkt.
Zusätzlich kann man Menüpunkte mit EnableMenu deaktivieren und wieder aktivieren oder
auch mittels CheckMenu mit einem Häkchen versehen. Menüpunkte können mit DeleteMenu
während des Programmlaufes entfernt werden oder mit InsertMenu ins Menü eingefügt
werden. Das ist z.B. unabdingbar, wenn man Programme schreibt, die in der Hauptschleife
kein WaitInput haben, aber trotzdem ein Menü besitzen. Nach Aufruf eines Menüpunktes
muß dann mit diesem Befehl %MenuItem z.B. auf 0 gesetzt werden.
Ein Sonderfall ist das Systemmenü, das immer dann vorhanden ist, wenn das Fenster den
entsprechenden Stil hat. Normalerweise werden die Ereignisse, die dieses Menü hervorruft,
automatisch von Windows behandelt. Will man aber gezielt auf dieses Menü, insbesondere
auf den Befehl "Schließen", reagieren, so kann der Programmierer die Verantwortung
übernehmen, indem der WindowsStil 256 zum Einsatz kommt. Solange das Programm
nichts entsprechendes vorsieht, bleiben alle Auswahlen des Systemmenüs wirkungslos. Es
werden aber folgende Menüpunkte in %MenuItem zurückgeliefert, die auch mit @MenuItem
abgefragt werden können:
-3808
-4064
-4048
-4000
-3792
Wiederherstellen
Verkleinern (zum Symbol)
Vergrößern (zum Vollbild)
Schließen (Alt-F4)
Wechseln zu ... (Taskmanager)
Folgende Zeilen würden ins Programm einzubinden sein, damit es wieder "normal"
funktioniert:
ElseIf @MenuItem(-3808)
ShowNormal
ElseIf @MenuItem(-4064)
ShowMin
ElseIf @MenuItem(-4048)
ShowMax
ElseIf @MenuItem(-4000)
End
Der Vorteil gegenüber dem von Windows kontrollierten Fenster: Hier könnten wir vor dem
END noch Sicherheitsabfragen einbauen, geänderte Dateien abspeichern und dergleichen
mehr.
Seite 108
RGH-PROFAN²
Mit dem Windowsstil 512 können wir einem Hauptfenster den Dialogfensterstil zuweisen. In
diesem Fall kann das Schließen des Fensters nur mit %Key = 2 abgefragt werden. Eine
Kombination dieses Stils mit 128 oder 256 ist nicht sinnvoll.
26.2 - Unabhängige PopUp-Menüs
Die zweite Sorte Menüs sind die unabhängigen PopUp-Menüs. Diese können an jedem Ort
erzeugt werden und verschwinden nach Auswahl eines Menüpunktes wieder. Mit
CREATEMENU beginnt ein solches Menü. Die Definition des Menüs erfolgt ebenso wie bei
den PopUp-Menüs des Fenster-Menüs. Angezeigt wird das Menü mit dem Befehl
TRACKMENU, dem als Parameter Koordinaten der oberen linken Ecke des Menüs folgen.
Der Befehl TRACKMENU wartet, bis ein Menüpunkt ausgewählt wurde. Häufig werden bei
kommerziellen Programmen solche Menüs dort angezeigt, wo die Maus gerade steht. Diese
Menüs werden meist mit der rechten Maustaste geöffnet. Hierzu ein kleines Beispiel:
Declare Ende%
Let Ende% = 0
WhileNot Ende%
If @Equ(%MouseKey,2)
CreateMenu
AppendMenu 101,"&blau"
AppendMenu 102,"&rot"
AppendMenu 103,"&grün"
Separator
AppendMenu 109,"&Ende"
TrackMenu %MouseX,%MouseY
If @MenuItem(109)
Let Ende% = 1
Else
Print "Ausgewählt:",%MenuItem
EndIf
EndIf
Wend
End
Seite 109
RGH-PROFAN²
26.3 - Warten auf Ereignisse
Im Zusammenhang mit Windows spricht man häufig von "ereignisorientierter
Programmierung". Was ist darunter zu verstehen? Bei den meisten Programmen ist es doch
so, daß immer nur dann etwas geschieht, wenn ich mit der Maus etwas anklicke oder
irgendeine Taste drücke. Ansonsten wartet Windows darauf, daß etwas passiert.Windows
wartet, bis ein Ereignis eintritt, um dann auf das Ereignis zu reagieren. Nach der Reaktion
auf das Ereignis oder schon während der Reaktion wartet Windows auf das nächste Ereignis.
In einem Windowsprogramm bedeutet dies, daß die meisten Routinen aufgrund eines
Ereignisses aufgerufen werden. Unser obiges Menüprogramm ist dafür ein Beispiel:
Windows wartet (bei WAITINPUT) auf ein Ereignis. Wenn dieses eintritt, wird überprüft, was
für ein Ereignis es war und je nach Ereignis wird die entsprechende Routine aufgerufen.
In PROFAN² kennen wir mehrere Befehle, um auf Ereignisse zu warten:
WAITKEY wartet auf einen Tastendruck. Dabei sind nur die 'normalen' alphanumerischen
Tasten gemeint, wobei auch deren Kombinationen mit <Strg> und <Shift> berücksichtigt
werden. Auf Sondertasten (Funktionstasten, Kursortasten, etc.) und Mausklick wird nicht
reagiert. Außerdem reagiert WAITKEY auch noch auf einige Systemereignisse, denen Codes
zugeordnet sind, die es nicht als Tasten gibt. Welches Ereignis (= welche Taste) es war,
steht in der Systemvariablen %KEY.
Wollen wir zusätzlich auch die erwähnten Sondertasten abfragen, müssen wir WAITSCAN
einsetzen. Das Ergebnis finden wir in %SCANKEY für die Sondertasten und in %KEY, falls
es eine 'normale' Taste war.
Sobald wir aber Buttons, ein Menü oder sonstige Dialogelemente mit im Programm haben,
wird man immer auch die Maus mit abfragen wollen. Hier wird WAITINPUT eingesetzt. Er ist
der umfassenste der Befehle, die auf ein Ereignis warten: WAITINPUT wartet, bis entweder
eine Taste oder ein Button gedrückt wurde, ein Element aus einer Listbox gewählt wurde, ein
Mausklick oder eine Menüauswahl erfolgte, in einem Editierfeld <Enter> gedrückt wurde, ...
Einige Ereignisse können nur mit WAITINPUT abgefragt werden, wie etwa %wmPaint,
%wmTimer oder F1 bei Dialogelementen.
Das Ereignis %wmTimer wird dann ausgelöst, wenn der Zeitgeber (Timer) mit SetTimer N&
eingestellt wurde, wobei N& den Zeitintervall in Millisekunden angibt. Alle N& Millisekunden
wird das Ereignis ausgelöst. Hinweis: Das Timerereignis wird nur ausgelöst, wenn ein
Hauptfenster existiert. Tip: Man kann auch unsichtbare Hauptfenster (Windowstyle 112,
Größe 0,0-0,0) erzeugen.
Ein zweites besonderes Ereignis ist %wmPaint, das je nach Einstellung durch SetAutoPaint
ausgelöst wird, wenn das Dialogfenster und/oder das Hauptfenster neuzuzeichnen ist.
Nähere Hinweise hieru finden sich im Kapitel über die Spezialitäten von PROFAN².
Das Ergebnis von WAITINPUT finden wir demzufolge in &MENUITEM, &KEY, &SCANKEY,
&MOUSEKEY, &MOUSEX und &MOUSEY. Wurde ein Dialogelement angeklickt, finden wir
dieses in %GETFOCUS. %wmTimer und %wmPaint werden auch entsprechend gesetzt.
Seite 110
RGH-PROFAN²
Ein typisches Windowsprogramm hat pro Fenster (bzw. Dialog) nur eine Stelle an der das
anliegende Ereignis ermittelt wird, gefolgt von Verzweigungen abhängig vom aufgetretenen
Ereignis. Das Ganze befindet sich in einer Schleife, die solange durchlaufen wird, bis das
Fenster verlassen wird (Programmende oder Beenden des Dialoges mit "OK"). Hier der
Ausschnitt einer solchen Fensterroutine:
Let Ende% = 0
WhileNot Ende
WaitInput
If @MenuItem....
...
ElseIf @MenuItem...
...
ElseIf @GetFocus...
...
ElseIf @KeyIn...
...
...
EndWhile
End
Diese Schleife wird solange durchlaufen, bis die Variable Ende% einen von 0 verschiedenen
Wert bekommt, etwa weil der Anwender den OK-Knopf drückt oder den Menüpunkt ENDE
auswählt.
Für jedes Fenster und jeden selbstdefinierten Dialog gibt es eine solche Schleife, in der das
Programm verbleibt, bis das Fenster/der Dialog verlassen wird.
Siehe hierzu auch die Grundstruktur eines Windowsprogrammes im Abschnitt FensterMenüs.
Hinweis: Auch ohne WAITINPUT oder WAITMOUSE ist die aktuelle Mausposition in
%MOUSEX und %MOUSEY vorhanden und die zuletzt gedrückte Maustaste in
%MOUSEKEY. Die aktuell gedrückte Maustaste ist in %MOUSEPRESSED. Während
%MOUSEKEY beim Auslesen auf 0 zurückgesetzt wird, hat %MouseKey solange den
entsprechenden Wert, solange die Maustaste gedrückt wird
Das Beispielprogramm für das unabhängige PopUp-Menü macht davon Gebrauch. Daher
kommt es ohne einen WAIT-Befehl aus. Das Hauptmodul selbst (zwischen WHILE und
ENDWHILE) ist die Warteschleife, die auf ein Ereignis wartet.
Wenn auch die Abfrage der Systemvariablen ausreichen würde, um das Ereignis näher zu
beschreiben, so gibt es in PROFAN² einige Funktionen, die dies erleichtern. Wollten Sie mit
den Systemvaraiblen herausbekommen, ob sich die Maus in einem bestimmten Bereich
befindet, ergäbe das eine recht lange verschachtelte Funktion mit mehreren @AND, @LT
und @GT. Das erspart uns die Funktion @MOUSE, die zwei Koordinatenpaare als
Parameter erwartet und den Wert 0 hat, wenn die Maus
außerhalb dieses Rechteches ist:
If @Mouse(10,10-60,60)
Print "Die Maus ist im Rechteck 10,10 - 60,60 !"
Else
Print "Daneben!"
EndIf
Die Abfrage der Systemvariablen %MENUITEM wird durch die Funktion @MENUITEM
vereinfacht, die Abfrage von %SCANKEY durch die Funktion @SKANKEY und die Abfrage
von %KEY durch die Funktion @KEYIN.
Seite 111
RGH-PROFAN²
In Anlehnung an BASIC gibt es noch zwei weitere Funktionen, um die Tastatur abzufragen:
Das ist einmal die Funktion @INKEY$(), die die augenblicklich gedrückte Taste zurückgibt
und die Funktion @GETKEY$(), die auf einen Tastendruck wartet und die Taste als Zeichen
zurückgibt.
Seite 112
RGH-PROFAN²
27 - Spezialitäten für Fortgeschrittene
27.1
Die Programmierung von Bidschirmschonern
Die Programmierung von Bildschirmschonern ist sicher eine sehr interessante Sache. Und
ab Version 3.0 ist dies in PROFAN² auch problemlos möglich. Windows erlaubt über die
Systemsteuerung die Einbindung von Bildschonern. Von diesen Bildschirmschonern werden
bei Windows einige wenige (und reichlich unspektakuläre) mitgeliefert. Diese
Bildschirmschonerdateien haben die Endung ".SCR". Tatsächlich aber ähnelt Ihr Aufbau sehr
dem Aufbau gewöhnlicher ".EXE"-Dateien.
Wer's nicht glaubt: Einfach eine ".SCR"-Datei in eine ".EXE"-Datei umbenennen! Nun kann
sie zwar nicht mehr als Bildschirmschoner eingesetzt werden, dafür aber unabhängig
gestartet werden.
Nun könnte man auf den Gedanken kommen, es reiche aus, eine ".EXE"-Datei in eine
".SCR"-Datei umzubenennen. Das funktioniert aus verschiedenen Gründen leider nicht:
Windows 3.x erkennt die Datei so nicht als Bildschirmschoner. Was hier noch fehlt, ist ein
Eintrag im "Header" der Programmdatei, der Windows sagt, daß dies ein Bildschirmschoner
ist und wie er heißt. Unter Windows 95 würde es prinzipiell gehen, aber hier wird das
Programm schon bei der Auswahl mit dem Parameter "/P" aufgerufen und würde dann
unvermittelt starten.
Für Bildschirmschoner hat die Entwicklungsumgebung von PROFAN² einen eigenen Punkt.
Wahlweise kann ein compiliertes PROFAN²-Programm zu einer gewöhnlichen EXE-Datei
oder aber zu einem Bildschirmschoner gelinkt (verbunden) werden. Der PROFAN²-Linker
trägt das Notwendige in den Header des Programmes ein und gibt ihm die Endung ".SCR".
In der 16-Bit-Version wird nun als Name des Bildschirmschoners der Dateiname
vorgeschlagen, aber Sie können einen anderen Namen eingeben. Windows 95 nutzt bei 32Bit-Bilschirmschonern grundsätzlich den Dateinamen.
(Wenn Sie den Linker unabhängig von der Entwicklungsumgebung aufrufen, geben Sie nach
dem Dateinamen den Parameter "/s" an. Beispiel: PROFLINK KREISE.PRC /s).
Auf diese Weise könnten Sie selbst aus einem Spiel einen Bildschirmschoner erzeugen. Das
würde aber wenig Sinn machen. Ein minimaler Bildschirmschoner sollte den Bildschirm
löschen (und zwar schwarz) und bei beliebigem Tastendruck oder Mausbewegung
verschwinden.
Unter Windows 95 muß zudem noch der Start verhindert werden, wenn das Programm mit
dem Kommandozeilenparameter "/P" aufgerufen wird. Damit wird der Bildschirmschoner bei
der Auswahl aufgerufen. Normalerweise dient dies dazu, den Vorschau-Bildschirm zu füllen.
Diese Funktion wird von PROFAN² noch nicht unterstützt.
Das erste Problem ist, den ganzen Bildschirm zu löschen, ohne Titelzeile oder Menü
anzuzeigen. Hierfür hat WindowStyle neue Stilelemente bekommen:
16
32
64
128
- Fenster hat zunächst kein Menü (also auch kein ©)
- Fenster benutzt Bildschirmhintergrund als Hintergrund
- Das Fenster hat keine Titelzeile
- Das Programm kann weder mit <Strg-Esc>, <Alt-Tab> noch <Alt-F4>
verlassen werden.
Seite 113
RGH-PROFAN²
Für den Bildschirmschoner benutzen wir all diese Elemente, macht zusammen 240 bzw.
$F0. Den Stil 32 nehmen wir deshalb, damit der Bildschirm nicht zunächst weiß gelöscht
wird. Das sieht so besser aus. Als nächstes öffnen wir das Fenster des Bildschirmschoners
über den gesamten Bildschirm. Die Auflösung des Bildschirmes erfahren wir über die
Systemvariblen %MaxX und %MaxY. Auch der CLS-Befehl wurde erweitert: Es ist jetzt
möglich die Farbe anzugeben, in der der Bildschirm gelöscht wird. Der Bildschirm soll
schwarz werden und deshalb nehmen wir die Farbe 0.
Um den Mauszeiger verschwinden zu lassen setzten wir den Befehl SHOWCURSOR ein.
WICHTIG: Vor dem Ende des Programmes muß der Mauszeiger wieder eingeschaltet
werden ... es sei denn, sie wollen Windows ausschließlich mit der Tastatur bedienen.
Als nächstes verharrt das Programm solange in der WHILE-Schleife, bis ein Tastendruck
oder eine Mausbewegung erfolgt. Um dies festzustellen benutzen wir die Systemvariable
%GETINPUTSTATE. Sie ist ungleich Null, sobald ein Maus- oder Tastaturereignis eintritt.
Die Variable TEST% wird heruntergezählt, sobald %GETINPUTSTATE ein solches Ereignis
meldet. Hat die Variable den Wert Null erreicht, wird die Schleife beendet, der Mauszeiger
wieder eingeschaltet und das Programm beendet. Damit der Bildschirmschoner nicht schon
beim Start gleich wieder endet, muß TEST% auf mindestens zwei gesetzt werden.
Eine weitere Sache muß noch berücksichtigt werden: Wenn der Screensaver eingeschaltet
ist, dann darf er nach der eingestellten Zeit nicht noch einmal eingeschaltet werden. Dieser
Aspekt wird leider oft übersehen (und wurde es auch von mir in den bisherigen Versionen).
Wenn man das nicht berücksichtigt, wird der Screensaver so oft gestartet, bis der Speicher
voll ist und nichts mehr geht. Abgesehen davon, daß es bei so langer Abwesenheit vom
Computer sinnvoller ist, wenigstens den stromfressenden Monitor auszuschalten, kann es
unter Umständen bei der ersten Mausbewegung dann eine Weile dauern, bis all die
Screensaver wieder geschlossen sind. Um dieses zu verhindern, wird beim Start des
Screensavers der entsprechende Eintrag in der SYSTEM.INI (Abteilung [boot]) auf "(Kein)"
gesetzt. Beim Verlassen des Screensavers wird wieder der usprüngliche Wert eingetragen,
der zuvor in einer Textvariablen gesichert wurde.
Hier das Listing eines minimalen Bildschirmschoners:
Declare Test%,Ini$,P$
If %ParCount
Let P$=@Upper$(@Par$(1))
EndIf
If @Neq$(P$,"/P")
Let Ini$=@ReadIni$("SYSTEM.INI","BOOT","SCRNSAVE.EXE")
WriteIni "SYSTEM.INI","BOOT","SCRNSAVE.EXE"="(Kein)"
WindowStyle $F0
Window 0,0 - %MaxX,%MaxY
Cls 0
ShowCursor 0
Let Test% = 2
While @Gt(Test%,0)
Case %GetInputState:Dec Test%
Wend
WriteIni "SYSTEM.INI","BOOT","SCRNSAVE.EXE"=Ini$
ShowCursor 1
EndIf
End
Mit %ParCount wird überprüft ob mindestens ein Parameter vorliegt. Dieser wird mit der
Funktion @Par$ ermittelt und in Großbuchstaben umgewandelt. Daher erfolgt der Vergleich
dann mit Großbuchstaben.
Seite 114
RGH-PROFAN²
Wenn wir diesen Bildschirmschoner über die Systemsteuerung (Abteilung "Desktop")
einbinden, stellen wir fest, daß er auch dann startet, wenn wir nicht den Button "Test"
drücken, sondern den Button "Einrichten" oder - unter Windows 95 - ein Paßwort einrichten
wollen. In diesen Fällen ruft Windows nämlich den Bildschirmschoner auf, aber bei
"Einrichten" wird noch der Kommandozeilenparameter "/c" angehängt und unter Windows 95
bei der Paßwortvergabe der Parameter "/a". Beim normalen Aufruf als Bildschirmschoner ist
dieser Parameter ein "/s".
In unserem zweiten Beispiel habe ich den Bildschirmschoner dahingehend erweitert, daß im
Falle des Einrichtens eine MessageBox aufgerufen wird und nach dieser das Programm
beendet wird. Außerdem habe ich den Schoner so erweitert, daß sich ein Icon über den
Bildschirm bewegt:
Declare X%,Y%,Test%,P$,Ini$
If %ParCount
Let P$ = @Upper$(@Par$(1))
EndIf
If @Equ$(P$,"/C")
@MessageBox("©1994 Roland G. Hülsmann","Icons",64)
ElseIf Neq$(P$,"/P")
Let Ini$=@ReadIni$("SYSTEM.INI","BOOT","SCRNSAVE.EXE")
WriteIni "SYSTEM.INI","BOOT","SCRNSAVE.EXE"="(Kein)"
WindowStyle $F0
Window 0,0 - %MaxX,%MaxY
Cls 0
ShowCursor 0
Let Test% = 2
Let X% = 0
Let Y% = 0
While @Gt(Test%,0)
Case %GetInputState:Dec Test%
Rectangle X%,Y% - @Add(X%,32),@Add(Y%,32)
Add X%,2
Add Y%,4
Case @Gt(X%,%MaxX):Let X% = 0
Case @Gt(Y%,%MaxY):Let Y% = 0
DrawIcon "GESICHT",X%,Y%
Wend
WriteIni "SYSTEM.INI","BOOT","SCRNSAVE.EXE"=Ini$
ShowCursor 1
EndIf
End
Natürlich könnte man jetzt in der 16-Bit-Version anstelle der einfachen Messagebox eine
Paßworteingabe einbauen. Dieses Paßwort könnte nun (verschlüsselt) in einer INI-Datei
gespeichert werden. Ebenso müßte der Bildschirmschoner dann das Paßwort abfragen,
sobald TEST% auf Null heruntergezählt wird. Wird ein falsches eingegeben müßte dann
TEST% wieder auf mindestens 2 hochgesetzt werden. Da der Windowstil 128 mit verwandt
wird, ist ein Abbruch der Paßwortabfrage über <Alt-F4>, <Strg-Esc> und dergleichen
unmöglich. In der 32-Bit-Version würde man sinnvollerweise, die Paßworteingabe
ermöglichen, wenn der Bildschirmschoner mit dem Paramer "/a" aufgerufen wird.
... und jetzt liegt es nur noch an Ihrer Phantasie und Kreativität, was Ihr Bildschirmschoner so
auf den Bildschirm bringt ... ob mit Musik oder ohne ... ob er Videos abspielt oder wahlweise
bunte Graphiken zeigt ... oder ob er gar ein Aquarium simuliert oder Toaster über den
Bildschirm fliegen läßt ...
Seite 115
RGH-PROFAN²
27.2
Neuzeichen selbst übernehmen
Wenn ein Fenster vergrößert und/oder verschoben wird, müssen Teile des Bildschirmes
und/oder Fensters neu gezeichnet werden.. Denn wenn es auch so aussieht, als ob der
Windowsbildschirm ein dreidimensionales Vor- und Hintereinander kennt, so ist er in der Tat
doch nur eine zweidimensionale Bitmap im Speicher, die der Grafikkartentreiber im Speicher
der Grafikkarte darstellt und die von dort aus auf Ihren Monitor gebracht wird. Jetzt mag man
als neuer Windowsprogrammierer hoffen, daß Windows diese Aufgabe des Neuzeichnens
und Aktualisierens übernimmt, aber wer dann mit C, C++ oder Pascal anfängt wird in dieser
Hoffnung enttäuscht. Was Windows macht ist folgendes: Es überwacht, ob ein Fenster
neugezeichnet werden müßte und sendet dem Fenster bzw. dem dazugehörigen Programm
die Aufforderung, sich neu zu zeichnen. Jetzt muß das Programm in der Lage sein, seinen
Bildschirminhalt neu zu zeichnen. Im Normalfall nimmt Ihnen PROFAN² diese Arbeit ab.
Solange in den Dialogboxen und Dialogfenstern nicht gezeichnet wird (siehe StartPaint EndPaint), benötgt das PROFAN²-Programm keine Kenntnis über diese Aufforderung. Wenn
man in Dialogfenstern zeichnet, so übernimmt hier PROFAN² das Neuzeichnen nicht
automatisch. Mit SetAutoPaint 1 sorgt man nun dafür, daß die Aufforderung zum
Neuzeichnen eines Dialogfensters WaitInput verläßt und die Systemvariable %wmPaint
gesetzt wird. Das Hauptfenster wird in diesem Fall weiterhin von PROFAN² automatisch
versorgt.
Es mag nun aber Fälle geben, wo der fortgeschrittene Programmierer auch dieses selbst in
die Hand nehmen möchte, etwa weil er die Größe der Hintergrundbitmap immer an die
Größe des Haupfensters angepaßt haben möchte. Dazu kann er mit SetAutoPaint 0 das
automatische Aktualisieren des Bildschirmes ausschalten und es selber übernehmen. In
diesem Fall wird die WindowsBotschaft wm_Paint, mit der Windows die Anwendung
unterrichtet, daß neugezeichnet werden muß, an das Programm weitergereicht, indem ggf.
ein WaitInput verlassen wird und die Systemvariable %wmPaint auf 1 gesetzt wird. Die
Routine, die beim Auftreten einer wm_Paint-Meldung aufgerufen wird, um das Hauptfenster
neu zu zeichnen, sollte in StartPaint %Hwnd - EndPaint eingeschlossen werden. Das ist dann
dringend notwendig, wenn in der Routine ein LoadBmp oder LoadSizedBmp vorkommt, da
diese Befehle sonst ein weiteres Neuzeichnen (zumindest im 256-Farben-Modus)
hervorrufen würden, was in einer unangenehmen Endlosschleife enden würde. Andere
Befehle, die ein Neuzeichnen des Bildschirmes nach sich ziehen, sind während des
Neuzeichnens desselben tunlichst zu vermeiden, wie etwa RePaint, Window oder
Messageboxen und die fertigen Dialoge.
Folgendes Beispielprogramm zeigt eine Bitmap immer in der Größe des Programmfensters
an und wird mit "Esc" beendet:
Declare Ende%
PROC MaleNeu
StartPaint %Hwnd
MCopySizedBmp 0,0-32,32 > 0,0-Width(%HWnd),Height(%HWnd);0
EndPaint
ENDPROC
CLS
MLoadBmp "TEST.BMP"
MaleNeu
Seite 116
RGH-PROFAN²
Let Ende% = 0
WHILENOT Ende%
WaitInput
IF %wmPaint
MaleNeu
ENDIF
IF @Equ(%Key,27)
Let Ende% = 1
ENDIF
ENDWHILE
END
27.3
Zeichnen in Dialogfenstern
Bis einschließlich Version 4.5 war es in PROFAN² nicht möglich, in einem anderen als dem
Hauptfenster zu zeichnen, Bitmaps zu laden und mit Drawtext Text zu plazieren.
Jetzt ist es möglich, die Bildschirmausgaben auf ein anderes Fenster umzuleiten, dessen
Handle bekannt ist. Zu diesem Zweck gibt es das Befehlspaar StartPaint / EndPaint.
StartPaint hat als Parameter das Handle des Fensters, auf das die Ausgabe umgeleitet wird.
Alle Grafikausgaben, die normalerweise auf das Hauptfenster erfolgen, erfolgen nun in das
neue Fenster. Dazu zählt auch UseFont und DrawText.
(Von der Umleitung ausgeschlossen sind jene Befehle, die den Textmodus von PROFAN²
betreffen, wie etwa LOCATE, PRINT, TBOX, ...) So ist es nun möglich in beliebige Fenster,
deren Handle man hat, zu malen, Text auszugeben, Bitmaps zu laden, etc.
WICHTIG: Jedem StartPaint muß (!) ein EndPaint folgen. Nach dem EndPaint erfolgen die
Ausgaben wieder auf das Hauptfenster (wenn eines existiert). Während der Druckausgabe
mit StartPrint - EndPrint ist der Befehl verboten.
NOCH WICHTIGER: Beim Zeichnen in DialogBoxen und DialogFenstern ist zu beachten,
daß diese Zeichnungen nicht automatisch erneuert werden, wenn die Dialogbox z.B. durch
ein anderes Fenster verdeckt wurde. Es ist also auf alle Fälle ratsam, mit SetAutoPaint 1
dafür zu sorgen, daß die Windowsbotschaft zum Neuzeichnen ausgewertet wird und eine
Prozedur zum Neuzeichnen des entsprechenden Dialoges oder Fensters veranlaßt wird.
Wenn AutoPaint mit SetAutoPaint 0 komplett ausgeschaltet ist, ist es durchaus sinnvoll (aber
nicht notwendig) die Ausgaben auf das Hauptfenster auch in StartPaint - EndPaint
einzuschließen, wobei dann als Fensterhandle %Hwnd zu nehmen ist.
27.4
Messageverwaltung selbst übernehmen
Diese Abschnitte sind in der Regel nur etwas für Fortgeschrittene, die sich schon in den
Tiefen der Windows-API auskennen. Dieses Handbuch kann und will keine Referenz der
API-Funktionen und Messages für Windows sein. Es gibt ausreichend Faschliteratur, die sich
mit diesem Thema beschäftigt.
Für gewöhnlich nimmt PROFAN² dem Programmierer viel von der Komplexheit der
Windowsprogrammierung ab und versteckt die komplizierteren Mechanismen in seinem
Interpreter bzw. Runtime-Modul. Gerade professionelle PROFAN²-Programmierer geraten
aber hin und wieder an die dadurch bedingten Grenzen von PROFAN². Schon in den
vergangenen Versionen wurden diese Grenzen für den PROFI gelüftet, indem der beliebige
Zugriff auf DLLs und Windows-API integriert wurde, die Resourcen genutzt und Messages
verschickt werden können. Der fortgeschrittene Programmierer kann selbst das Neuzeichnen
von Fenstern übernehmen.
Seite 117
RGH-PROFAN²
Der nächste Schritt in diese Richtung ist ein erweitertes Messagehandling: Der Befehl
GETMESSAGE wartet auf die nächste Message für das PROFAN²-Programm. Sobald diese
eintritt, werden die Systemvariablen %MESSAGE (seit 4.5 schon undokumentiert
vorhanden), %MWND, &WPARAM und &LPARAM mit den entsprechenden Werten gefüllt.
Anschließend wird die Messageverwaltung an Windows zurückgegeben. Das bedeutet, daß
Messages, wie etwa Fenster vergrößern, verkleinern, verschieben etc. immer noch von
Windows bearbeitet werden. Aber auch diese Messages können nun vom Programm
zusätzlich behandelt werden. HINWEIS: Die PROFAN²-Systemvariablen, die für gewöhnlich
von den WAIT-Befehlen gesetzt werden (etwa %SCANKEY, %KEY, %MENUITEM, etc.)
werden bei GETMESSAGE in der Regel auch gesetzt. Diese Messages kommen unter
Umständen erst gar nicht bei GETMESSAGE an. Hier ist im Zweifelsfalle Ausprobieren
angesagt.
%MESSAGE enthält die Nummer der zuletzt aufgetretenen Message. Eine Liste findet sich
im Anhang des Handbuches zu PROFAN².
%MWnd enthält das Handle des Fensters, an das die Message gerichtet war.
&WPARAM und &LPARAM sind Message-abhängige Parameter, in denen zusätzliche
Informationen stehen. Diese sind von Message zu Message verschieden. In der 16-BitVersion enthält &WPARAM nur einen 16-Bit-Wert (WordPARAMeter), &LPARAM hingegen
einen 32-Bit-Wert (LongintPARAMeter). Im 32-Bit-Windws sind beide Parameter 32-Bit breit,
die Namen wurden aber aus historischen Gründen beibehalten. In PROFAN² sind aus
Kompatibilitätsgründen in beiden Versionen beide Systemvariablen als LongintSystemvariablen ausgelegt. (&WPARAM und &LPARAM entsprechen dem dritten und
vierten Parameter bei @SENDMESSAGE und @POSTMESSAGE.)
Seite 118
RGH-PROFAN²
Mit %PEEKMESSAGE ist es möglich, die gerade anliegende Message abzufragen, ohne
diese aus der Warteschlange zu entfernen oder zu verarbeiten. Hat die Systemvariable dem
Wert 0, lag keine Message an, anderenfalls werden %MESSAGE, %MWND, &WPARAM
und &LPARAM entsprechend gefüllt.
Ein kleines Programm zum Austesten der Messages:
CLS
DECLARE %Ende
LET Ende% = 0
WHILENOT %Ende
GETMESSAGE
LOCATE 0,0
PRINT "Meldung: ";%Message;"
"
PRINT "Fenster: ";%MWnd;"
"
PRINT "WParam: ";&WParam;"
"
PRINT "LParam: ",&LParam;"
"
IF @Equ(%Message,$0204)
' wm_RButtonDown
LET %Ende = 1
ENDIF
ENDWHILE
END
Das Programm wird durch Drücken der rechten Maustaste beendet.
Es können mit auf diese Weise auch selbstdefinierte Messages behandelt werden. So ist es
möglich, daß ein PROFAN-Programm auf Messages reagiert, die ihm ein anderes per
@POSTMESSAGE sendet! Um nicht mit den Windowsmessages ins Gehege zu kommen,
sollten selbstdefinierte Messages eine Messagenummer größer als $1000 haben!
Wenn auch die üblichen WAIT-Befehle nicht auf alle Messages reagieren, so werden doch
die Systemvariablen %MESSAGE, %MWND, &WPARAM und &LPARAM immer korrekt
gefüllt. Das gilt auch für Schleifen ohne jeden WAIT-Befehl oder GETMESSAGE.
27.5
Zur Verwendung von DLLs
Bis Version 5.0 wurde bei mehrfacher Verwendung von @USEDLL nur die zuletzt genutzte
DLL im Speicher gehalten. Jeder @USEDLL-Aufruf hatte die zuvor geladene DLL aus dem
Speicher entfernt. Das ist nun nicht mehr so. Es können nun beliebig viele DLLs geladen
werden. Um sie aus dem Seicher zu entfernen ist der Befehl FREEDLL zu verwenden.
@USEDLL und FREEDLL können auch sinnvoll sein, um häufige Aufrufe von DLLFunktionenm zu optimieren. Wenn eine DLL nämlich schon im Speicher ist, wie sie beim
Aufruf der externen DLL-Funktion nicht erneut von Platte geladen, sondern die Kopie im
Speicher verwandt. Bei externen DLLs, die Initialisierungsaufrufe beinhalten oder wo
Eigenschaften von anderen DLL-Funktionen eingestellt werden können, ist es häufig sogar
notwendig vor dem ersten Aufruf die DLL mit @USEDLL in den Speicher zu laden, damit die
von einem Aufruf gemachten Einstellungen auch bei weiteren Aufrufen verfügbar sind. Wird
nämlich mit einer definierten Funktion eine Funktion einer externen DLL aufgerufen, die sich
noch nicht im Speicher befindet, wird diese für die Funktion geladen und anschließend
wieder entladen. Das kostet zum Einen Zeit und zum Anderen gehen gemachte
Einstellungen beim Entladen verloren.
Seite 119
RGH-PROFAN²
28 - Kompatibilität zu früheren PROFAN-Versionen
PROFAN 4.x / 5.x
PROFAN² 6.0 ist 100%ig Quelltext-kompatibel zu PROFAN² 4.x und 5.x. Aus
Kompatibilitätsgründen werden auch noch GOTO, GOSUB und Labels unterstützt. Es kann
jedoch nicht garantiert werden, daß diese Befehle auch noch in künftigen Versionen
vorhanden sind.
Beim Upgrade auf die 32-Bit-Version kann es sein, daß die Funktionen, die einen Focus
oder Fensterhandle ermitteln, andere Ergebnisse bringen, da die Trennung der
Anwendungen untereinander (eigener Adreßraum, Multithreading, etc.) größer ist als unter
Windows 3.1. Ebenso werden SENDKEY und SENDSTRING unter Umständen
unterschiedlich funktionieren, insbesondere wenn ein 32 Bit Programm versucht, mit einem
16-Bit-Programm zu kommunizieren oder umgekehrt. Ein ausführlicher Test ist in jedem Fall
also angesagt. DDE kennt jedoch keine Unterschiede. Die Messagenummern für
Dialogelemente sind in der 16- und 32-Bit-Version unterschiedlich. Hier ist die Referenz bzw.
einschlägige Fachliteratur zu Rate zu ziehen.
Da das Format des Zwischencodes beibehalten wurde, ist eine Neucompilierung nicht
notwendig. Das neue 6.0 Runtime-Modul kommt sowohl in der 32- als auch der 16-BitVersion mit den bisherigen PRC-Dateien (ab Version 3.0) klar.
PROFAN 3.x
PROFAN² 6.0 ist 100%ig Quelltext-kompatibel zu PROFAN² 3.x. Lediglich die Befehle und
Funktionen, die aus Kompatibilität zu Version 1.x noch enthalten waren (DIM, LIST, @LIST
ohne Datentypkennung) werden nicht mehr unterstützt. Ersetzen Sie diese einfach durch
DIM%, LIST% und @LIST%.
Da das Format des Zwischencodes beibehalten wurde, ist eine Neucompilierung nicht
notwendig. Trotzdem ist es empfehlenswert, alle Programme neu zu compilieren, da in der
neuen Version auch einige Bugs auzsgemerzt wurden.
PROFAN 2.x
PROFAN² 6.0 ist 100%ig Quelltext-kompatibel zu PROFAN² 2.x. Lediglich die Befehle und
Funktionen, die aus Kompatibilität zu Version 1.x noch enthalten waren (DIM, LIST, @LIST
ohne Datentypkennung) werden nicht mehr unterstützt. Ersetzen Sie diese einfach durch
DIM%, LIST% und @LIST%.
Das Format des Zwischencodes mußte jedoch (zur Temposteigerung etc.) verändert werden,
sodaß es NICHT möglich ist, eine alte compilierte 2.x-PRC-Datei mit der neuen 6.0RUNTIME zu starten. Es reicht jedoch aus, den bisherigen Quelltext neu zu compilieren.
Künftige PROFAN-Versionen
Künftige PROFAN-Versionen werden - soweit technisch sinnvoll und möglich - 100%ig
Quelltext-kompatibel zu PROFAN² 6.0 sein. Solange noch 16-Bit-Versionen nachgefragt
werde, werden diese weiterentwickelt.
Seite 120
RGH-PROFAN²
Programmieren für Anwender
P R O F A N ² 6.0
DIE einfache Programmiersprache
für Windows 3.x und Windows 95
Teil 2: Programmierkurs
Seite 121
RGH-PROFAN²
0 - Vorbemerkung
Rufen Sie einfach PROFAN² über den Dateimanager auf und Sie gelangen in die
Entwicklungsumgebung. Die Entwicklungsumgebung der 16-Bit-Version ist PROFED.EXE
und die der 32-Bit-Version ist PROFED32.EXE. Hier können Sie Programme entwickeln,
speichern und starten. Damit PROFAN² auch als Batchsprache seinen vollen Nutzen
entwickeln kann, empfiehlt es sich, unter Windows 3.x in der Datei "WIN.INI" im Abschnitt
"[Extensions]" folgende Zeile einzutragen: "PRF=C:\PROFAN\PROFAN.EXE ^.PRF", wobei
Sie natürlich Ihren Pfad zu PROFAN.EXE eintragen müssen. Jetzt können Sie im
Dateimanager PROFAN²-Programme durch Doppelklick starten ohne eigens PROFAN²
aufrufen zu müssen. Unter Windows 95 ist die Verknüpfung entsprechend der Anleitung bzw.
Hilfe zu Windows 95 zu erstellen.
Natürlich können Sie auch PROFAN.EXE mit Kommandozeilenparameter starten, etwa
"PROFAN
MYLLDEMO.PRF".
Ebenso
können
Sie
PROFAN.EXE
ohne
Kommandozeilenparameter starten (etwa durch Doppelklick im Dateimanager) und mittels
der sich dann öffnenden Datei-Auswahl-Box das passende Programm auswählen.
Ich gehe davon aus, daß Sie die Syntax (Schreibweise) der Befehle in der Referenz zu
PROFAN² nachsehen und verzichte im Kurs daher auf umfassende Syntax-Beschreibungen.
Dieser Kurs soll Einführung und Referenz nicht ersetzen, sondern ergänzen.
Hinweis: In eckigen KLammern sind in der Referenz gewöhnlich Parameter gezeigt, die auch
weggelassen werden können.
Seite 122
RGH-PROFAN²
1 - PROFAN² als Batchsprache
Ein Batchprogramm dient in der Regel dazu, immer wiederkehrende Abläufe zu
automatisieren. DOS hat dazu eine leistungsfähige BATCH-Sprache, aber unter Windows
gibt es nichts dergleichen. In diese Lücke zielt PROFAN² als Batchsprache!
PROFAN² startet den EDITOR
Nehmen wir einmal an, Sie wollen Texte mit dem Windowseditor NOTEPAD.EXE
bearbeiten. Aus Sicherheitsgründen wollen Sie sich immer eine Sicherheitskopie anlegen,
die den Namen "KOPIE.DOK" haben soll. Ihre Textdokumente befinden sich im Verzeichnis
"C:\DOKUS" und haben die Endung "DOK". Ohne PROFAN² müßten Sie nun zuerst mit dem
Dateimanager den gewünschten Text nach "KOPIE.DOK" kopieren, den Editor aufrufen, die
vorgegebene Endung mit "*.DOK" überschreiben, in das Verzeichnis wechseln und die
gewünschte Datei laden. Sie könnten natürlich auch zuerst die Datei laden, under dem
Namen "KOPIE.DOK" mit "SPEICHERN ALS" abspeichern und dann erneut die Datei laden,
... oder aber Sie schreiben Sich folgendes kleines PROFAN²-Programm:
(1)
(2)
(3)
(4)
DECLARE Datei$
LET Datei$ = @LOADFILE$("Text laden","C:\DOKUS\*.DOK")
COPY Datei$ > "C:\DOKUS\KOPIE.DOK"
RUN @ADD$("NOTEPAD.EXE ",Datei$)
Um das Programm zu schreiben, starten Sie den PROFAN²-Editor PROFED.EXE. Das geht
auch direkt aus dem Programmanager über das entsprechende Icon in der PROFAN²Programmgruppe. Geben Sie nun das Programm (ohne die Zahlen in den runden
Klammern) ein. Dieses Programm können wir z.B. unter dem Namen "DOKU.PRF"
speichern. Dazu wählen wir den Menüpunkt "DATEI . SPEICHERN ALS". Über den
Menüpunkt "PROFAN - AUSFÜHREN" können wir nun das Programm starten. Zu den
Programmzeilen im Einzelnen:
(1) In PROFAN² müssen Variablen vor Ihrer ersten Benutzung deklariert werden. Dies
geschieht mit dem Befehl DECLARE. Hinter DECLARE können auch mehrere Variablen
angegeben werden. Wie vom BASIC her gewohnt, wird die Art der Variable durch das letzte
Zeichen (Postfix) angegeben:
$ = String (max. Länge 255 Zeichen)
% = Integer (Ganzzahl: -32767 - 32767)
& = Langer Integer (Große Ganzzahl: ca. -2 Mia - 2 Mia)
! = Fließkommazahl (mind. 14 genaue Stellen)
# = Bereichsvaiable (Speicherbereich - unter 16 Bit nur bis 64 kB)
In unserem Fall wird eine Stringvariable mit Namen "Datei$" angelegt.
(2) Hinter der Funktion @LOADFILE$ verbirgt sich ein kompletter Dialog zum Laden eines
Dateinamens. Der erste Parameter ist die Überschrift des Datei-Dialoges, während der
zweite Parameter Pfad und Suchmaske angibt. In unserem Beispiel werden alle Dateien mit
der Endung "DOK" zur Auswahl angeboten, die sich im Verzeichnis "C:\DOKUS" befinden.
Das Ergebnis der Wahl wird der Variablen "Datei$" zugewiesen.
Übrigens: Alle Funktionen in PROFAN² können mit einem "@" beginnen. Zum einen kann
das Programm dadurch übersichtlicher werden und zum anderen erkennt der Interpreter
sofort, daß eine Funktion kommt, was das Programm im Interpretermodus (Batchbetrieb)
schneller macht.
Seite 123
RGH-PROFAN²
(3) Als Nächstes kopieren wir diese Datei nach "KOPIE.DOK". Der COPY-Befehl ähnelt sehr
dem gleichnamigen DOS-Kommando. Es ist aber darauf zu achten, daß zwischen Quelldatei
und Ziel-Datei das Größer-Zeichen steht. Es symbolisiert die Richtung in die kopiert wird.
Außerdem kann in PROFAN² immer nur eine Datei kopiert werden.
(4) Mit dem Befehl RUN starten wir nun den Windows-Editor NOTEPAD.EXE. Mit der
Funktion @ADD$ werden die Strings "NOTEPAD.EXE " und Datei$ zu einem String
verbunden. Vergessen Sie nicht das Leerzeichen hinter NOTEPAD.EXE! Mit dem RUNBefehl endet unser PROFAN²-Programm und die Kontrolle wird an den aufgerufenen Editor
übergeben.
PROFAN² stellt Fragen
Es kann nun natürlich auch der Fall eintreten, daß wir die Sicherungskopie nicht immer
machen wollen. Es wäre ganz praktisch, den Anwender zu fragen, ob er eine
Sicherheitskopie haben will. Anhängig von der Antwort muß das Programm dann die
Sicherungskopie erstellen oder gleich die Datei öffnen. Erweitern wir also unser Programm:
(1)
(2)
(3)
(4)
(5)
(6)
(7)
DECLARE Datei$, Antwort%
LET Datei$ = @LOADFILE$("Text laden","C:\DOKUS\*.DOK")
LET Antwort% = @MESSAGEBOX ("Wollen Sie eine \
Sicherungskopie erstellen?","Frage:",36)
IF @EQU(Antwort%,6)
COPY Datei$ > "C:\DOKUS\KOPIE.DOK"
ENDIF
RUN @ADD$("NOTEPAD.EXE ",Datei$)
Folgende Erweiterungen wurden notwendig:
(1) In der ersten Zeile kommt die Variable ANTWORT% hinzu, um - wie der Name vermuten
läßt, die Antwort auf unsere Frage aufzunehmen.
(3) Mit der Funktion @MESSAGEBOX bringen wir eine windowstypische Dialogbox auf den
Bildschirm. Die Funktion hat drei Parameter: Der erste Parameter ist der Meldungstext, der
in der Box erscheint. Der zweite Parameter ist die Überschrift, die in der Titelzeile der Box
auftaucht. Besonders wichtig ist der dritte Parameter: Er gibt Auskunft über Anzahl der
Knöpfe, benutztes Symbol, etc.! Er setzt sich zusammen aus BUTTONS + ICON +
DEFAULT + FENSTERART. Die entsprechenden Werte entnehmen wir der Referenz zu
PROFAN². In der Referenz sind sie bei der Funktion @MESSAGEBOX aufgeführt. Zunächst
sollen zwei Buttons vorhanden sein, nämlich "JA" und "NEIN". Der Wert für BUTTONS ist
also die 4. Als Icon (Sinnbild) empfiehlt sich das Fragezeichen: 32. DEFAULT gibt an,
welcher Knopf angewählt sein soll und mit ENTER angewählt wird. Das soll der erste, der
"JA"-Knopf sein: 0. Da es eine normale Meldungsbox sein soll, ist auch der vierte Wert eine
0. Wenn wir die gefundenen Werte addieren (4 + 32 + 0 + 0), erhalten wir 36. Das ist der
gesuchte Wert.
Eine weitere Besonderheit zeigt Zeile 3: Der Backslash am Ende der Zeile zeigt an, daß der
Befehl in der nächsten Zeile weitergeht, und zwar beim ersten Zeichen, das kein Leerzeichen
ist. Auf diese Weise kann eine Befehlszeile auf mehre Textzeilen umgebrochen werden.
Übrigens: Die maximale Länge einer Befehlszeile sind 254 Zeichen.
Sobald wir einen der beiden Buttons betätigen, verschwindet die Messagebox vom
Bildschirm und gibt den gedrückten Button zurück. Der Referenz entnehmen wir, daß der
"JA"-Knopf den Wert 6 zurückliefert.
Seite 124
RGH-PROFAN²
(4) Hier steht der IF-Befehl. Hinter dem IF steht der Bedingungsausdruck. Wenn er den Wert
0 hat, ist die Bedingung nicht erfüllt und die Zeile(n) zwischen IF und ENDIF wird (werden)
nicht ausgeführt. Der Bedingungsausdruck ist hier die Funktion @EQU. Diese Funktion
überprüft die Gleichheit der beiden Werte. Sind beide Werte gleich (d.h. war der gedrückte
Knopf das "JA") ist die Bedingung erfüllt, ansonsten eben nicht. Wenn die Bedingung erfüllt
ist, wird Zeile (5) ausgeführt, ansonsten geht es gleich weiter zu Zeile (7).
HINWEIS 1: Da PROFAN² keine Operatoren kennt (siehe Einführung), ist ein Ausdruck wie
etwa "IF ANTWORT% = 1" nicht möglich. Aber für alle Operatoren und Verknüpfungen (* - +
/ AND OR ...) gibt es entsprechende Funktionen.
HINWEIS 2: Das aus BASIC oder PASCAL bekannte "THEN" gibt es in PROFAN² nicht.
HINWEIS 3: Natürlich gibt es auch "ELSE" und "ELSEIF". Die Referenz gibt darüber
Auskunft.
Eine letzte Ergänzung
Zum Schluß des ersten Teils wollen wir noch festlegen können, welchen Namen die
Sicherungskopie der Datei haben soll. Hierzu bietet PROFAN² die Funktion @SAVEFILE$:
(1)
(2)
(3)
(4)
(5)
(6)
(7)
(8)
(9)
(10)
DECLARE Datei$, Kopie$, Antwort%
LET Datei$ = @LOADFILE$("Text laden","C:\DOKUS\*.DOK")
LET Antwort% = @MESSAGEBOX ("Wollen Sie eine \
Sicherungskopie erstellen?","Frage",36)
IF @EQU(Antwort%,6)
LET Kopie$ = @SAVEFILE$("Name der Kopie", \
"C:\DOKUS\KOPIE.DOK")
IF @NEQ$(Kopie$,"")
COPY Datei$ > Kopie$
ENDIF
ENDIF
RUN @ADD$("NOTEPAD.EXE ",Datei$)
(1) Zunächst brauchen wir eine weitere Variable, um den Namen für die Kopie zu speichern.
Wir nennen diese Varaible sinnigerweise KOPIE$.
(5) Die Funktion @SAVEFILE$ erinnert sehr an @LOADFILE$: Der erste Parameter ist die
Überschrift des Dialoges und der zweite der vorgeschlagene Dateinahme. Im Dialog hat der
Anwender die Möglichkeit, den Namen zu ändern oder auch ein anderes Verzeichnis zu
wählen. Die Funktion gibt Pfad und Namen der tatsächlich gewählten Datei zurück.
(6) Die Funktion @NEQ$ prüft zwei Strings auf Ungleichheit. Hier ist die Bedingung also
erfüllt, wenn der Inhalt von KOPIE$ kein leerer String ist. Ein leerer String wäre er aber,
wenn der Anwender im @SAVEFILE$-Dialog den Knopf "Abbrechen" gedrückt hätte. Das "$"
am Ende des Funktionsnamens sagt hier aus, daß Strings (und keine Zahlenwerte)
verglichen werden. Folgende Vergleichsfunktionen kennt PROFAN²:
Für Zahlenwerte:
@EQU Gleichheit
@LT
Kleiner als
@GT
Größer als
@NEQ Ungleicheit
Seite 125
RGH-PROFAN²
Für Strings:
@EQU$ Gleichheit
@LT$ Kleiner als
@GT$ Größer als
@NEQ$ Ungleicheit
Nähere Hinweise finden sich unter den betreffenden Stichworten in der Referenz der Hilfe zu
PROFAN².
Seite 126
RGH-PROFAN²
2 - EVA - Eingabe > Verarbeitung > Ausgabe
EIN- UND AUSGABE
Was fällt Ihnen bei EVA ein? Wahrscheinlich zunächst nicht ein grundlegendes Prinzip der
Datenverarbeitung. Und doch wird mit EVA die grundlegende Funktion fast jedes
Programmes bzw. Programm-Modules beschrieben: EINGABE - VERARBEITUNG AUSGABE. Die Daten werden zunächst in irgendeiner Form eingegeben, dann verarbeitet
und schließlich die Ergebnisse ausgegeben.
Die Eingabe erfolgt in vielen Fällen über die Tastatur oder über Dateien, die vom Programm
gelesen werden. (Andere Eingabemöglichkeiten sind über zahlreiche Zusatzgeräte wie etwa
Scanner, AD-Wandler, Schalter, Relais, ... aber auch Videokammera, Mikrophon, ...)
Die Ausgabe der verarbeiteten Daten erfolgt bei uns meist über Bildschirm, Drucker und
Dateien, in die die Daten geschrieben werden. (Natürlich gibt es auch Plotter, Soundkarten,
Videogeräte und vielerlei mehr ... bis hin zur Steuerung von Modelleisenbahn, Stereoanlage
und Roboter ...)
Eine leistungsfähige Sprache für Windows benötigt natürlich Befehle, um die Ein- und
Ausgabe von Daten zu ermöglichen. PROFAN² ist hier besonders vielseitig.
BILDSCHIRM, TASTATUR UND DRUCKER IM TEXTMODUS
Textmodus unter Windows? Nun, ein richtiger Textmodus ist es nicht, aber es wird der DOSBildschirm mit 80 Zeichen pro Zeile simuliert. Es gibt keinen Befehl, um in den Textmodus
zu schalten: In PROFAN² ist der Textmodus - neben dem windowseigenen Grafikmodus immer verfügbar. Der Textmodus wurde eingebaut, um die Ein- und Ausgabe mit den von
BASIC her bekannten Befehlen zu ermöglichen:
CLS löscht den Bildschirm
PRINT gibt Daten (Strings und Zahlen) aus
LOCATE positioniert den Cursor
COLOR stellt die Farben für den PRINT-Befehl ein
INPUT ermöglicht die Eingabe von Daten
Ein kleines Beispiel: EVA1.PRF
( 1)
( 2)
( 3)
( 4)
( 5)
( 6)
( 7)
( 8)
( 9)
(10)
(11)
(12)
(13)
(14)
DECLARE Name$, Alter%
CLS
LOCATE 2,2
PRINT "TESTPROGRAMM"
LOCATE 4,2
PRINT "Wie heißt Du? ";
INPUT Name$
LOCATE 6,2
PRINT "Wie alt bis Du? ";
INPUT ALTER%
LOCATE 8,2
PRINT "Du heißt",Name$,"und bist",ALTER%,"Jahre alt."
WAITKEY
END
Seite 127
RGH-PROFAN²
Einem BASIC-Programmierer kommt wahrscheinlich alles recht bekannt vor. Es gibt jedoch
einige Unterschiede. Gehen wir das Programm Zeile für Zeile durch:
( 1) - Die Variablen werden declariert. Das gibt es in BASIC nicht.
( 2) - Der Bildschirm wird gelöscht.
( 3) - Der Cursor wird positioniert (Zeile 2,Spalte 2).
( 4) - Es wird Text ausgegeben.
( 6) - Die Frage wird ausgegeben. Das Semikolon am Ende der Zeile sorgt dafür, daß der
folgende Befehl an der gleichen Cursor-Position aufsetzt:
( 7) - Der Name wird eingeben. Achtung: Bei INPUT darf keine Textausgabe (wie etwa in
BASIC stehen). Hinter INPUT dürfen nur Variablennamen stehen.
(10) - Das Alter wird eingegeben.
(12) - Das Ergebnis wird ausgegeben. Das Komma sorgt jeweils dafür, daß die Ausgaben
durch ein Leerzeichen getrennt sind. Bei einem Semikolon würde kein Leerzeichen kommen.
(13) - WAITKEY wartet auf einen Tastendruck und END beendet das Programm.
Wir können das Ergebnis auch in eine Datei schreiben. Dazu fügen wir zwischen WAITKEY
und END noch folgende Zeilen ein (EVA2.PRF im BEISPIEL-Verzeichnis):
(a)
(b)
(c)
(d)
(e)
ASSIGN #1,"ERGEBNIS.DAT"
REWRITE #1
PRINT #1,Name$
PRINT #1,Alter%
CLOSE #1
(a) - Dem Kanal Nr. 1 wird mit ASSIGN der Dateiname "ERGBNIS.DAT" zugewiesen.
(b) - Der Kanal wird mit REWRITE zum Schreiben geöffnet. Die Datei wird somit erzeugt.
(c) Der Name wird mit in die Datei geschrieben.
(d) Das Alter wird in die Datei geschrieben.
(e) Der Kanal (und damit die Datei) wird geschlossen.
Übrigens: PROFAN² kennt 15 Kanäle (1 - 15). BASIC-Programmierer werden sich über (a)
und (b) wundern. Hier habe ich Anleihen von PASCAL genommen. In BASIC würden die
beiden Zeilen zu einer zusammengefaßt:
OPEN "ERGEBNIS.DAT" FOR OUTPUT AS #1
Mit folgendem kurzen Programm können wir die in "ERGEBNIS.DAT" geschrieben Daten
wieder auslesen:
( 1)
( 2)
( 3)
( 4)
( 5)
( 6)
( 7)
( 8)
( 9)
(10)
DECLARE Name$, Alter%
CLS
ASSIGN #1,"ERGEBNIS.DAT"
RESET #1
INPUT #1,Name$
INPUT #1,Alter%
PRINT "Du heißt",Name$,"und bist",ALTER%,"Jahre alt."
CLOSE #1
WAITKEY
END
Kurze Erläuterung:
( 4) - RESET öffnet den Kanal zum Lesen
( 5) - Der Name wird aus der Datei gelesen
( 6) - Das Alter wird aus der Datei gelesen
Seite 128
RGH-PROFAN²
Normalerweise ist ein Drucken im Textmodus nicht vorgesehen. Wenn Sie zwischen
STARTPRINT und ENDPRINT den PRINT-Befehl versuchen, gibt PROFAN² eine
entsprechende Fehlermeldung aus. Mit einem kleinen Trick gelingt es uns aber trotzdem:
Wir weisen einem Kanal den Drucker zu, indem wir als Dateiname "PRN" angeben. Alle
Ausgaben in diesen Kanal gelangen dann zum Drucker:
ASSIGN #1,"PRN"
REWRITE #1
PRINT #1,Name$;" ist ";Alter%;" Jahre alt."
PRINT #1,@Chr$(12)
CLOSE #1
HINWEIS: In der 16-Bit-Version müssen Sie vorher die Zeile SETLFN 0 einfügen, wenn Sie
unter Windows 95 arbeiten. Ansonsten wird "PRN" nicht als Drucker erkannt.
Mit @Chr$(12) geben wir das Zeichen mit dem ASCII-Code 12 an den Drucker. Das ist das
Zeichen für das Seitenende. Wenn wir anstelle von "PRN" die serielle Schnittstelle
ansprechen wollen, benutzen wir als Dateinamen "COM1" oder "COM2".
Den Abschluß dieses Abschnittes bildet ein kleines Programm, mit dem wir unsere
PROFAN²-Listings ausdrucken können. Es heißt "LLIST.PRF" und befindet sich im
BEISPIEL-Verzeichnis Ihrer PROFAN²-Installation.
Listing: LLIST.PRF
Declare Datei$,Zeile$
SetLFN 0
Let Datei$ = @LoadFile$("PROFAN-Datei auswählen:","*.PRF")
IFNOT @Equ$(Datei$,"")
Cls
Assign #1,Datei$
Reset #1
Assign #2,"PRN"
Rewrite #2
WHILENOT @Eof(#1)
Input #1,Zeile$
Let Zeile$ = @AnsiToOem$(Zeile$)
Print #2,Zeile$
WEND
Close #1
Print #2,@Chr$(12)
Close #2
ENDIF
END
Drei Erläuterungen zu dem Programm:
Die Befehle, die zwischen WHILENOT und WEND bzw. ENDWHILE stehen, werden solange
wiederholt, solange die Bedingung nicht erfüllt ist. (Sollten Sie solange wiederholt werden,
solange die Bedingung erfüllt ist, müßte die Schleife mit einem WHILE beginnen.)
Die Bedingung heißt hier @EOF(#1). EOF steht für "End of File". Die Funktion hat dann den
Wert 1 (= Bedingung erfüllt), wenn das Ende der Datei im angegebenen Kanal erreicht ist. In
unserem Beispielprogramm, wird der eingelesene Text solange auf den Drucker gegeben,
bis das Ende der PROFAN²-Datei erreicht ist.
Seite 129
RGH-PROFAN²
Der Drucker eines PC-Benutzers wird in der Regel auf den erweiterten ASCII-Zeichensatz
eingestellt sein. (Bei Nadeldruckern heißt er meißt "IBM2", beim HP-Laserjet hingegen
"PC8".) Windows hingegen nutzt in der Regel den ANSI-Zeichensatz, bei dem die deutschen
Sonderzeichen andere Codes haben. Die Funktion @AnsiToOem$ wandelt einen String vom
Ansi-Zeichensatz in den ASCII-Zeichensatz um.
Der Windows-Modus
Mit dem bisher Gelernten läßt sich ja schon einiges anstellen, aber wie richtige
Windowsprogramme sehen die Ergebnisse noch nicht aus.
Unter Windows geschieht viel mit Dialogboxen und Fenstern. Natürlich beherrscht dies auch
PROFAN². Unser Beispielprogramm sähe dann so aus (EVA3.PRF):
(1)
(2)
(3)
(4)
(5)
(6)
DECLARE Name$, Alter%, Text$
Let Name$ = @Input$("Wie heißt Du?","Frage:","")
Let Alter% = @Input$("Wie alt bist Du?","Frage",99)
Let Text$ = "Du heißt",Name$,"und bist",Alter%,"Jahre alt."
@MessageBox(Text$,"Ergebnis:",64)
END
Einige Erläuterungen:
(2) - Mit der Funktion @INPUT$ können sowohl Strings als auch numerische Werte
eingelesen werden. Der erste Parameter ist die Frage, bzw. Erläuterung zur Eingabe. Der
zweite Parameter ist die Überschrift des Eingabefensters. Der dritte Parameter ist der
Vorgabewert, also der Wert, der im Eingabefeld als Vorschlag angeboten wird.
(3) - Die Funktion funktioniert auch mit Zahlenwerten. In unserem Beispiel ist der
Vorgabewert 99.
(4) - Mit dem LET-Befehl können, durch Kommas oder Semikolons getrennt, wie beim
PRINT-Befehl mehrere Strings zusammengefügt werden. Bei einem Komma wird ein
Leerzeichen eingefügt.
(5) - Die Messagebox kennen wir bereits aus dem letzten Kursteil.
Da dieses Programm keine direkten Ausgaben in ein Hauptfenster macht, gibt es dieses
nicht: Kein CLS und kein WINDOW-Befehl. Eine besondere Errungenschaft von Windows
3.1 waren die TrueType-Schriften. Endlich gab es brauchbare Schriften, die auf Bildschirm
und Drucker (weitestgehend) gleich aussahen. Zudem ließen sich die TrueType-Schriften in
beliebiger Richtung auf dem Bildschirm und Drucker ausgeben. Diese Möglichkeiten können
wir auch unter PROFAN² ausschöpfen. Das Programm "TRUETYPE.PRF", das Sie im
BEISPIEL-Verzeichnis finden, demonstriert dies eindrucksvoll.
Listing: TRUETYPE.PRF
Declare Grad%, Text$, Ende%
Proc TextDemo
Declare Winkel%,Groesse%
TextColor @RGB(0,0,0),-1
Let Text$ = ".......... PROFAN²"
Let Winkel% = 150
WhileNot @Gt(Winkel%,3600)
Let Groesse% = @Div(Winkel%,100)
Orientation Winkel%
UseFont "Times New Roman",Groesse%,0,0,0,0
DrawText 250,180,Text$
Add Winkel%,150
Wend
EndProc
Seite 130
RGH-PROFAN²
Proc Bildschirm
Cls
TextDemo
EndProc
Proc Drucker
StartPrint
TextDemo
EndPrint
EndProc
WindowTitle "TrueType - Demo"
Window 0,0 - 639,479
PopUp "&Ausgabe"
AppendMenu 100,"&Bildschirm"
AppendMenu 101,"&Drucker"
Separator
AppendMenu 109,"&Ende"
Let Ende% = 0
WhileNot Ende%
WaitInput
Case @MenuItem(100):Bildschirm
Case @MenuItem(101):Drucker
Case @MenuItem(109):Let Ende% = 1
Wend
End
An dieser Stelle noch einige Erläuterungen zum Programm:
PROFAN² kennt Prozeduren. Diese werden durch PROC, gefolgt vom Prozedurnamen,
eingeleitet und mit ENDPROC abgeschlossen. Diese Prozedurdefinition muß vor dem ersten
Aufruf erfolgen. Im Programm können dann die Prozeduren mit Ihrem Namen aufgerufen
werden. In "TRUETYPE.PRF" werden drei Prozeduren definiert:
TEXTDEMO
Diese Prozedur leistet die eigentliche Arbeit. Mit TEXTCOLOR wird die Schriftfarbe
eingestellt. Der erste Parameter ist die Vordergrundfarbe. Diese kann eine der 32768 in
PROFAN² möglichen Farben sein. Die hier eingesetzte Funktion @RGB ermittelt aus den
Werten für Rot, Grün und Blau (je von 0 bis 31) den entsprechenden Farbwert. In unserem
Beispiel sind R, G und B jeweils 0, also ist die Farbe schwarz. Der zweite Parameter von
TEXTCOLOR ist die Hintergrundbarbe. Die -1 bedeutet "transparent", d.h. es wird die
vorhandene Hintergrundfarbe so gelassen wie sie ist.
mit ORIENTATION stellen wir den Winkel der Textausgabe ein. Der Winkel wird in
Zehntelgrad angegeben. In der Schleife wird der Winkel von 15 bis 360 Grad in Schritten zu
je 15 Grad erhöht. Gleizeitig wird die Schriftgröße von 1.5 bis 36 erhöht.
USEFONT stellt die Schrift ein. Der erste Parameter ist der Schriftname und der zweite die
Größe der Schrift. Der dritte Parameter ist die Schriftbreite; ist er 0, wird eine Standardbreite
benutzt. Die übrigen drei Paramer können die Werte 0 oder 1 annehmen uns stehen für fett,
kursiv und unterstrichen. Mit DRAWTEXT wird der Text an die entsprechende
Bildschirmposition bzw. Druckposition gebracht.
Seite 131
RGH-PROFAN²
BILDSCHIRM
Der Bildschirm wird gelöscht und TEXTDEMO wird aufgerufen.
DRUCKER
Mit STARTPRINT wird die Ausgabe auf den Drucker umgeleitet. Dann wird TEXTDEMO
aufgerufen. Alle DRAWTEXT-Befehle gehen jetzt auf den Drucker. Mit ENDPRINT wird die
Druckseite abgeschlossen und die Ausgabe wieder auf den Bildschirm geleitet. Das
anschließende Hauptprogramm stellt mit WINDOWTITLE die Fensterüberschrift ein und mit
WINDOW die Größe. Da WINDOW das Fenster auch gleichzeitig auf den Bildschirm bringt,
erübrigt sich hier ein CLS.
Dann wird das Menü erzeugt und in der PROFAN²-typischen WHILE-Schleife je nach
Menüauswahl verzweigt.
Seite 132
RGH-PROFAN²
3 - Sound & Vision
Die meisten Windowsprogrammiersprachen haben wenige bis gar keine Möglichkeiten zur
Sounderzeugung oder Anzeige von Bitmaps. Visual Basic kann zwar sehr gut mit Bitmaps
und Icons umgehen, bleibt aber stumm. Im Handbuch findet sich nur der Hinweis, daß die
Befehle BEEP, SOUND und PLAY nicht unterstützt werden. Turbo- Pascal für Windows
erlaubt wenigstens den Piepser (MessageBeep), aber fertige Routinen zum Anzeigen von
Bitmap-Bildern sucht man vergebens ... wie überhaupt die Grafikprogrammierung unter
Turbo-Pascal für Windows eine äußerst komplexe Geschichte ist ...
PROFAN² hingegen kennt zahlreiche Möglichkeiten, Ihrem PC mit oder ohne Soundkarte
Töne zu entlocken und auch die Anzeige von Bitmap-Grafiken ist problemlos ebenso
möglich, wie das Zeichnen komplexer Grafiken.
Auf eines soll allerdings hingewiesen werden: Die Töne BEEP, SOUND, PLAY und MUSIC
funktionieren in der Regel problemlos über den eingebauten Lautsprecher. Bei einer
Soundkarte hängt es davon ab, inwieweit der Treiber die diesen Befehlen zugrundeliegenden
Windowsfunktionen unterstützt oder unverändert an den Lautsprecher weiterleitet. Microsoft
selbst garantiert nicht, daß die Funktionen auch in künftigen Windowsversionen vorhanden
sein werden, da die Möglichkeiten der Multimedia-Schnittstelle weitreichender seien. BEEP
sollte aber auf alle Fälle funktionieren. Wenn Sie nichts hören, sollten Sie in der
Systemsteuerung unter "Klänge" das Kästchen "Systemklänge aktivieren" ankreuzen.
Der Piepser in Aktion
Die einfachste Möglichkeit, ein Geräusch zu erzeugen, ist der BEEP Befehl. Er erzeugt einen
kurzen Warnton. Wenn in der Systemsteuerung allerdings dem Ereignis 'Kritischer Abbruch'
eine WAV-Datei zugewiesen ist, wird diese abgespielt.
In folgendem Beispielprogramm zu Errechnung der Fakultäten von 1 bis 25 wird der BEEPBefehl benutzt, um den Anwender auf eine falsche Eingabe hinzuweisen:
DECLARE A%,OK%,Ergebnis!
WHILENOT OK%
LET A%=@INPUT$("Bitte eine Zahl zwischen 1 und 25 eingeben:",\
"EINGABE",A%)
IF @OR(@Lt(A%,1),@Gt(A%,25))
BEEP
ELSE
LET OK%=1
ENDIF
WEND
LET Ergebnis! = @Pow(A%,A%)
DECIMALS 0
@MESSAGEBOX(@Str$(Ergebnis!),"ERGEBNIS",0)
In der IF-Bedingung werden die beiden Bedingungen "A kleiner als 1" (@LT(A%,1)) und "A
größer als 25" (@GT(A%,25)) mit der OR-Funktion verknüpft. Das heißt: Die Bedingung ist
erfüllt wenn A kleiner als 1 ist ODER A größer als 25!
Für komplexere Geräusche gibt es noch den SOUND-Befehl, der als Parameter die Tonhöhe
in Hertz und die Dauer in 360tel Sekunden hat.
Seite 133
RGH-PROFAN²
Noten mit PLAY
Will man nun kurze Tonfolgen programmieren, die auch nach etwas klingen, so ist es doch
recht hinderlich, immer in einer Notentabelle nachzusehen, welcher Ton welche Frequenz
hat. Mit PROFAN² ist dies auch nicht nötig, da es den PLAY-Befehl gibt. Der PLAY-Befehl
hat drei Parameter, die es ermöglichen, jedweden Ton zu spielen:
Tonhöhe: der erste Parameter ist die Tonhöhe ausgehend vom tiefsten Ton mit der Nummer
1. Von da wird in Halbtonschritten hochgezählt. Eine Oktave umfaßt 12 Halbtonschritte.
Tonlänge: Hier wird die Tonlänge in einer für Musik brauchbaren Schreibweise angegeben: 1
steht für eine ganze Note, 2 für eine halbe, 4 für eine Viertel ... bis hin zu 32 für eine
zweiundreißigstel. Daß Sie auch eine siebtel Note spielen könnten, mag zwar interessant
klingen, ist aber für die Musik von relativ untergeordneter Bedeutung.
Der dritte Parameter ermöglicht das Spielen punktierter Noten, indem er die Anzahl der
Punkte angibt. Ein Punkt verlängert die Dauer einer Note um die Hälfte Ihrer Länge.
Das folgende Beispielprogramm spielt eine Tonleiter in Viertel-Noten:
PLAY
PLAY
PLAY
PLAY
PLAY
PLAY
PLAY
PLAY
12,4,0
14,4,0
16,4,0
17,4,0
19,4,0
21,4,0
23,4,0
24,4,0
Bevor Sie aber jetzt anfangen, Ihren Lieblingssong auf diese Weise in ein Programm
umzuwandeln, schauen Sie sich den mächtigsten der Tonbefehle an:
MUSIC mit der Sprache in der Sprache
Vielleicht kennen Sie von BASIC her den Befehl PLAY. Der dient dort nicht zum Abspielen
einzelner Noten, sonderm zum Abspielen kompletter Melodien. Die einzelnen Noten werden
mittels einer Music-Makro-Sprache in einen String gestellt und dieser wird dem Befehl als
Parameter übergeben. Diese Makrosprache gibt es auch in PROFAN² und wird dort mit dem
Befehl MUSIC ausgeführt.
Auf einen Unterschied sei allerdings hingewiesen: Das Abspielen im Hintergrund ist nicht
möglich. Ansonsten enthält die Makrosprache alle Befehle:
Noten werden durch Ihre Bezeichnung dargestellt:
MUSIC "C D E F G A B"
Dieser Befehl spielt die C-Dur-Tonleiter. Die Leerzeichen zwischen den Tönen können auch
weggelassen werden.
HINWEIS: Im internationalen Gebrauch bezeichnet B den Ton, der im deutschen
Sprachraum mit H bezeichnet wird. Wenn wir im deutschen Sprachraum B sagen, meinen
wir das erniedrigte H.
Natürlich können wir auch eine Oktave höher oder tiefer gehen. Dazu dienen das ">" und das
"<". Direkt einstellen können wir die Oktave mit dem Befehl "O" gefolgt von der Nummer der
Oktave, die zwischen 1 und 8 liegen darf:
Seite 134
RGH-PROFAN²
MUSIC "O3 C D E F G A B > C"
Die ersten sieben Töne werden in der 3. Oktave gespielt und das letzte C in der vierten.
Natürlich sind wir nicht auf C-DUR (bzw. A-MOLL) beschränkt, und können die Noten auch
um je einen Halbton erhöhen und erniedrigen. Zum Erhöhen verwenden wir das "#" und zum
Erniedrigen das "-". Hier die Tonleiter in G-DUR:
MUSIC " O3 G A B > C D E F# G"
Bisher wurden alle Noten in einer Länge gespielt. Voreingestellt sind viertel Noten. Die Länge
können wir beeinflussen, indem wir mit "L" gefolgt von der Notenlänge die Länge aller
folgenden Noten einstellen oder indem wir an Note die Längenbezeichnung direkt anhängen:
MUSIC "L2 C D E F G4 A16"
Hier werden die Noten C bis F als halbe Noten gespielt, das G ist eine viertel Note und das A
eine sechzehntel. Um punktierte Noten zu spielen, wird an die Längenbezeichnung einfach
ein Punkt angehängt: "G4." würde eine punktierte Viertelnote spielen. Auch das Grundtempo
können wir angeben, indem wir den Befehl "T" verwenden, gefolgt von der Anzahl der
Viertelnoten pro Minute. Voreingestellt ist der Standardwert von 120. Pausen spielen wir mit
dem Notenwert "P". Neben der Kennzeichnung eines Tones mit der Notenbezeichnung,
können wir eine Note auch über ihren Wert kennzeichnen, indem wir den Befehl "N" gefolgt
von der Nummer der Note verwenden. Dabei werden die Töne vom tiefsten Ton mit der
Nummer 1 einfach hochgezählt (wie der erste Parameter bei PLAY). Eine zusätzliche
Angabe einer Notenlänge ist hier nicht möglich. Es wird immer der mit "L" eingestellte Wert
verwandt.
Mit den Befehlen "ML", "MN" und "MS" kann die Spielweise noch zwischen "Legato" (Töne
gehen ineinander über), "Normal" und "Staccato" (Töne klingen abgehackt) variiert werden.
Das Beispielprogramm CELLO.PRF spielt ein Stück für Cello in G- DUR.
Listing: CELLO.PRF
Music "t110 o2 l8 ml"
Music
Music
Music
Music
"g > d b4 a b16 > c16 < b a g f# g d"
"e g > c < a f# > d < b2 a. p16"
"< a > f# > c4 < b > c16 d16 c < b a g f# e"
"f# g16 a16 g f# e f# d4 < a4 d. p16"
Music
Music
Music
Music
"g > d b4 a b16 > c16 < b a g f# g d"
"e g > c < a f# > d < b2 a. p16"
"< a > f# > c4 < b > c16 d16 c < b a g f# e"
"f# g16 a16 g f# e f# d4 < a4 d. p16"
Music
Music
Music
Music
">
"<
"<
"a
d f# a4 g a16 b16 a g f# e d f#"
b > d g# a b > d << a >> d c < b > c. p16"
d# f# a > c < b a b e < g > a > c < b"
g f# e < b > d# < e4 p > e d c"
Music
Music
Music
Music
"<
">
">
"d
b > d g4 d e16
c# e a4 e f#16
d f# a > c < b
< f# t94 g < b
f32
g32
> d
t84
p32
p32
< e
d >
f d e c < c b"
g e f# d < d a"
g b > d c e"
f# g2."
Seite 135
RGH-PROFAN²
Selbstverständlich können die Strings auch Stringvariablen sein. Während des Abspielens
eine Strings reagiert der Computer auf keinerlei Aktionen. Achten Sie also darauf, daß die
einzelnen Strings nicht zu lang werden.
VON BITMAPS UND ICONS
Was wäre ein Windowsprogramm, wo ich nicht durch Anklicken von Icons irgendwas
auswählen kann oder was lediglich einen langweiligen weißen Hintergrund bietet? Daß
PROFAN² mehr kann, zeigen ja schon die Demos, die bei PROFAN² mitgeliefert werden.
Die Anzeige von Bitmaps
Was sind Bitmaps? Bitmaps sind in diesem Zusammenhang Bilder, wo jedes Bit für eine
Grafik-Information steht; Bilder die pixelweise aufgebaut werden. Windows hat hier ein
eigenes Bildformat, das durch die Endung .BMP gekennzeichnet ist. Zwei weitere Formate
sind sehr ähnlich: nämlich das Format ".RLE" (komprimierte Bitmap-Bilder) und das Format
".DIB". All diese Formate können von PROFAN² mit den gleichen Befehlen geladen werden.
In PROFAN² gibt es zwei Befehle um Bilder zu laden und auf den Bildschirm zu bringen:
LOADBMP und LOADSIZEDBMP. Ersterer lädt das Bild und zeigt es in der Originalgröße
an. Daher hat dieser nur vier Parameter: Name der Bilddatei (evtl. mit Pfad),X-Koordinate
der linken oberen Ecke, Y-Koordinate der linken oberen Ecke und den Abbildungsmodus.
Beispiel:
LOADBMP "PARTY.BMP",10,10;0
Der Abbildungsmodus beschreibt, wie das Bild mit dem, was schon auf dem Bildschirm ist,
verknüpft wird. Im Abbildungsmodus 0 wird das, was schon auf dem Bildschirm ist,
überschrieben. Die weiteren Modi sind in der Referenz zu PROFAN² beschrieben.
Wenn das Bild nun aber in einer anderen Größe angezeigt werden soll, müssen wir den
zweiten Befehl verwenden. Hier geben wir auch noch die Breite und Höhe der Anzeige mit
an. Beispiel:
LOADSIZEDBMP "PARTY.BMP",10,10 - 100,100;0
Wenn wir für Länge und/oder Breite negative Zahlen einsetzen ist sogar eine "verdrehte"
bzw. "gespiegelte" Anzeige möglich. VORSICHT: Je nach Grafiktreiber und Farbtiefe kann
es bei 256farbigen Bildern zu unerwarteten Abbildungsergebnissen kommen, wenn sie mit
LOADSIZEDBMP geladen werden. Hier hilft nur ausprobieren, was geht und was nicht geht.
Wenn ich z.B. im 256-Farben-Modus ein Bild mit 256 Farben lade und verkleinere sieht das
Ergebnis ziemlich schwarz aus. Bin ich hingegen im 16-Farben- oder 32000-Farben-Modus
gibt es keine Probleme. Beim Laden mit LOADBMP sollte es hingegen immer optimal
aussehen!
Seite 136
RGH-PROFAN²
Als Beispiel ein Programm zur Anzeige von Bitmaps:
Declare Name$
WindowTitle "BILD-BETRACHTER"
CLS
ShowMax
Let Name$=@LoadFile$("Bilddateien","*.BMP")
WhileNot @Equ$(Name$,"")
Cls
LoadBmp Name$,0,0; 0
WindowTitle @Add$("BILD-BETRACHTER - [",@Add$(Name$,"]"))
WaitMouse
Let Name$=@LoadFile$("Bilddateien","*.BMP")
EndWhile
End
Was wäre Windows ohne Icons?
Auch PROFAN² kennt ICONS. Und da die DEMO-Programme davon reichlich Gebrauch
machen, sei hier nur auf das Wesentliche hingewiesen:
In PROFAN² gibt es zum einen die SYSTEM-Icons und zum anderen die PROFAN²-Icons.
Die System-Icons sind die bekannten Symbole, die auch in den Messageboxen auftauchen.
Sie sind durchnumeriert und werden mit dem Befehl DRAWSYSICON auf den
Bildschirmgebracht:
DRAWSYSICON 4,30,30
Der erste Parameter bezeichnet das Icon und die beiden anderen Parameter sind die
Koordinaten, an denen das Icon angezeigt wird. Es gibt die Icons 0 bis 4: leeres Rechteck,
STOP-Zeichen, Fragezeichen, Ausrufezeichen und Info-Zeichen.
Desweiteren enthält PROFAN² 19 verwendbare Icons, die über Ihren Namen mit dem Befehl
DRAWICON angezeigt werden:
DRAWICON "EIMER",80,80
Folgende Icons sind in PROFAN² bekannt: PROFAN, KNOPF1, KNOPF2, BAUM, EIS,
COMPUTER, DOS, WEG, TEXT, GESICHT, EDITOR, EIMER, MUELL, MUENZE, SAND,
STEIN, WINDOWS und WASSER.
Sie sind allerdings nicht auf diese Icons beschränkt. Mit vielen auf dem Shareware-Markt
erhältlichen ICON-Managern, können Sie diese Icons verändern, gegen andere austauschen
und gar noch welche hinzufügen. Das Programm muß in der Lage sein, Icons in EXEDateien zu bearbeiten. ACHTUNG: Da Sie bei diesen Vorhaben dann die EXE-Datei
(PROFAN.EXE) verändern, machen Sie vorher eine Sicherheitskopie.
Ein ausgezeichnetes Beispiel, wie Icons für Spiele als Sprites zu "mißbrauchen" sind, zeigt
das Beispielprogramm "MÜLLSPIEL".
Seite 137
RGH-PROFAN²
4 - Multimediaprogrammierung mit PROFAN²
DIE MCI-SCHNITTSTELLE
MCI steht für "Multimedia Controlling Interface", was wörtlich übersetzt MultimediaSteuerschnittstelle bedeutet. Diese Schnittstelle verbindet mich mit allen in Windows
integrierbaren Multimediatreibern. Sobald ein neuer Treiber installiert ist, wie z.B. ein Treiber
für Autodesk-Animationen, kann ich ihn über diese Schnittstelle ansprechen. Die Schnittstelle
ist sehr einfach gehalten. Es gibt eigentlich nur drei Befehle bzw. Funktionen, über die ich
mit den Treibern kommuniziere:
1.
Ich sende einen Befehl an den Treiber. Die Syntax des Befehles wird u.A. auch
vom Treiber mitbestimmt. (Nicht alle Treiber unterstützen alle Befehle.)
2.
Als Ergebnis des Befehles liefert der Treiber a) unter Umständen ein Ergebnis und
b) einen Fehlercode zurück, wobei 0 für eine fehlerfreie Funktion steht. Und da nur der
Treiber weiß, was der Fehlercode bedeutet, gibt es eine dritte Funktion:
3.
Ich übermittle dem Treiber die Fehlernummer und der Treiber liefert im Gegenzug
die Fehlerbeschreibung im Klartext. Handelt es sich um deutsche Versionen der Treiber, sind
diese sogar in Deutsch. Die mit Windows 3.1 mitgelieferten Treiber für CD, MIDI und WAVE
liefern deutsche Fehlermeldungen.
MCI MIT PROFAN²
In PROFAN² sind die drei Funktionen mit einer Funktion und einer Systemvariablen
realisiert:
Mit der Funktion @MCISEND$ sende ich einen Befehl an die Multimediaschnittstelle. Konnte
dieser Befehl fehlerfrei ausgeführt werden, liefert die Funktion gegebenenfalls das Ergebnis
als String zurück. Im Fehlerfall wird hingegen die Fehlermeldung zurückgegeben. Damit ich
als Programmierer nun weiß, ober der Rückgabestring ein Ergebnis oder eine Fehlermeldung
ist, gibt es noch die Systemvariable %MCIERROR, die den Fehlercode enthält. Hat
%MCIERROR einen von 0 verschiedenen Wert, hat die Funktion @MCISEND$ eine
Fehlermeldung zurückgeliefert.
Hier gleich ein erstes kurzes Programm, mit dem wir die MCI-Schnittstelle testen können.
Das Programm macht nichts anderes, als einen eingegebenen Befehl an die MCISchnittstelle zu schicken und das Ergebnis mitzuteilen.
Listing: MCITEST.PRF
Declare Zeile%,Befehl$,Meldung$
WindowTitle "MCI-Testprogramm in PROBAT"
Window 20,20-600,400
Let Zeile% = 0
Let Befehl$ = @Input$("Bitte geben Sie einen MCI-Befehl ein:",\
"MCI-BEFEHL","")
Seite 138
RGH-PROFAN²
WhileNot @Equ$(@Upper$(Befehl$),"ENDE")
If @GT(Zeile%,20)
Cls
Let Zeile% = 0
EndIf
Print "Befehl: ";Befehl$
Inc Zeile%
Let Meldung$ = @MCISend$(Befehl$)
If %MCIError
Print "Fehler: ";
Else
Print "OK!
";
EndIf
Print Meldung$
Inc Zeile%
Let Befehl$ = @Input$("Bitte geben Sie einen MCI-Befehl ein:",\
"MCI-BEFEHL","")
EndWhile
End
Über die @INPUT$-Funktion wird der MCI-Befehl eingegeben. Sowohl der Befehl als auch
das Ergebnis wird auf den Bildschirm gegeben, damit man die Ergebnisse der letzten
Befehle vor Augen hat. Die Variable ZEILE% zählt die Zeilen, um den Bildschirm zu löschen,
bevor er voll wird. Diese Prozedur wird solange wiederholt, bis der Anwender "Ende" eingibt:
Die Schleife zwischen WHILENOT und WEND wird erst dann verlassen, bis die
Abbruchbedingung hinter WHILENOT erfüllt ist.
Die Funktion @UPPER$ wandelt den String in Großbuchstaben um, sodaß es egal ist, ober
der Anwender "ENDE", "ende" oder gar "enDe" eingibt. Eine Besonderheit: Auch die
deutschen Umlaute werden korrekt behandelt.
Der Befehl INC erhöht die Integervariable (nur da ist er erlaubt) um 1. (Mit DEC erreichen wir
das Gegenteil.)
Ein Hinweis noch: Der Befehl WINDOW stellt die Fenstergröße ein. Damit läßt sich die
Größe des Programmfensters beliebig einstellen.
CD-PLAYER
Am Beispiel des Abspielens einer CD im CD-ROM-Laufwerk schauen wir uns die
Funktionsweise des Programmes und der MCI-Schnittstelle etwas genauer an:
Jedes Multimediagerät muß zunächst geöffnet werden. Dabei ist es möglich, dem Gerät
einen Alias-Namen zu geben. Das ist quasi eine Kurzform, um es einfacher ansprechen zu
können. WICHTIG: Der gleiche Alias-Name darf nicht mehrmals zur gleichen Zeit in
Gebrauch sein.
Um ein Gerät zu öffnen, wird der Befehl OPEN benutzt, gefolgt von der Gerätebezeichnung.
Diese wird vom Treiber festgelegt. Öffnen wir die CD:
OPEN CDAUDIO ALIAS CD
Geben Sie diesen Befehl in die Input-Box unseres Programmes ein. Wenn tatsächlich eine
CD im Laufwerk liegt, wird kurz darauf ein "OK!" auf dem Bildschirm erscheinen.
Jetzt wollen wir die Länge der CD in Erfahrung bringen. Um etwas über das geöffnete Gerät
zu erfahren, gibt es den STATUS-Befehl, gefolgt vom Gerätenamen (oder der Kurzform) und
der der Angabe, was wir wissen wollen:
Seite 139
RGH-PROFAN²
STATUS CD LENGTH
Als Ergebnis wird die Länge der CD ausgeben. Nun wollen wir noch die Anzahl der Titel
wissen:
STATUS CD NUMBER OF TRACKS
Bevor wir jetzt das Gerät abspielen können, müssen wir uns auf ein Zeitformat einigen. Hier
gibt es mehrere Möglichkeiten. Für eine CD ist aber lediglich das TMSF-Format von
Bedeutung. Das Zeitformat "TMSF" bedeutet, daß Start und Ende im PLAY-Befehl im
Format "Track:Minute:Sekunde:Frame" angegeben werden, wobei eine Sekunde 75
"Frames" (kleinste Einheit) hat. Es könnten also beliebige Bruchstücke eines Titels gespielt
werden. Wir wollen die CD aber ab dem 7. Titel spielen. Zum Abspielen gibt es den PLAYBefehl:
PLAY CD FROM 7
Hätte uns nur ein Teil des Titels interessiert hätten wir auch eingeben können:
PLAY CD FROM 7:1:0 TO 7:1:10
Jetzt werden gerade mal 10 Sekunden aus der Mitte des Titels gespielt. Wie wir hier sehen,
können wir die nicht benötigten kleineren Unterteilungen der Zeitangabe weglassen. Wollten
wir nur die dritte Minute des Titels spielen, geben wir ein:
PLAY CD FROM 7:2 TO 7:3
HINWEIS: Die Titelnummern (Track) beginnen bei 1, Minuten und Sekunden beginnen bei 0.
Wollen wir die CD anhalten geben wir ein:
STOP CD
Da wir den Treiber mit OPEN geöffnet haben schließen wir ihn nach getaner Arbeit wieder:
CLOSE CD
Natürlich können wir diese Befehle auch in einem Programm einbauen. Um z.B. den 3. bis 5.
Titel einer CD abzuspielen, können wir schreiben:
@MCISend$("open cdaudio alias cd")
Print "Länge: ";@MCISend$("status cd length")
Print "Titelzahl: ";\
@MCISend$("status cd number of tracks")
@MCISend$("set cd time format tmsf")
@MCISend$("play cd from 3 to 5")
WaitInput
HINWEIS: Wird das Programm beendet, bevor der 5. Titel fertig ist, spielt die CD
anschließend weiter, da der CD-Spieler dann nicht mehr vom Programm bzw. der
Multimediaschnittstelle von Windows kontrolliert wird.
Weitere interessante MCI-Befehle zum Ansteuern der CD finden Sie in der Einführung zu
PROFAN² unter der Rubrik "Multimedia".
Seite 140
RGH-PROFAN²
Einem selbstprogrammierten CD-Player steht nun nichts mehr im Wege. Ein Tip: Unter den
Icons, die in PROFAN² integriert sind, gibt es zwei Knöpfe: Einer in ungedrückter und einer in
gedrückter Form. Hiermit lassen sich die notwendigen Buttons auf den Bildschirm bringen,
um den CD-Player zu steuern. Näheres hierzu unter DRAWICON in der Hilfe zu PROFAN².
WAVE UND MIDI, FLI/FLC UND AVI MIT PROFAN²
Beim Öffnen eines Gerätes, daß einen Dateinamen benötigt, gibt es eine Erweiterung des
OPEN-Befehles: Mit TYPE muß ich angeben, um welchen Datei-Typ es sich handelt.
Im Falle einer WAV-Datei ist der Type "WAVEAUDIO". Also öffnen wir eine Datei:
OPEN TOCCATA.WAV TYPE WAVEAUDIO ALIAS TOCCATA
WICHTIG: Damit keine Fehlermeldung kommt, muß sich die Datei TOCCATA.WAV im
aktuellen Verzeichnis befinden. Um Sie zu spielen geben wir den PLAY-Befehl ein:
PLAY TOCCATA
Anschließend schließen wir das Gerät wieder:
CLOSE TOCCATA
Wenn wir eine WAV-Datei nicht mit unserem MCI-Testprogramm abspielen, sondern in
einem Programm, können wir es wie folgt programmieren:
@MCISend$("open toccata.wav type waveaudio alias toccata")
@MCISend$("play toccata wait")
@MCISend$("close toccata")
Zwischen PLAY und CLOSE muß natürlich genug Zeit gelassen werden, die Datei zu
spielen. Damit der Computer solange wartet, bis der PLAY-Befehl abgearbeitet ist, kann man
den Zusatz WAIT mit angeben. Aber Achtung: Während dieser Zeit, ist keine weitere Aktion
möglich. Der WAIT-Befehl ist daher nur mit Vorsicht einzusetzen. Unabdingbar ist er, wenn
ich eine WAV-Datei aufnehmen will. Das geht mit folgender Befehlsfolge (das Mikrofon sollte
angeschlossen und bereit sein):
Zuerst teilen wir mit, daß wir eine neue Datei erzeugen wollen:
OPEN NEW TYPE WAVEAUDIO ALIAS SPRUCH
Nun setzen wir das Zeitformat auf Millisekunden:
SET SPRUCH TIME FORMAT MILLISECONDS
Und jetzt nehmen wir in 5 Sekunden unseren dümmsten Spruch auf:
RECORD SPRUCH FROM 0 TO 5000 WAIT
Natürlich wollen wir hören, wie die Aufnahme geworden ist:
PLAY SPRUCH FROM 0
Seite 141
RGH-PROFAN²
Wenn die Aufnahme gelungen ist, speichern wir sie ab:
SAVE SPRUCH SPRUCH.WAV
Die anderen in der Überschrift des Artikels genannten Dateitypen sind in der Behandlung
sehr ähnlich. Genauer gesagt: Es ändert sich nur das Befehlswort, das hinter TYPE steht.
Folgende Dateitypen beherrscht Windows 3.1 von Hause aus:
*.WAV Sound-Dateien
Typ: WAVEAUDIO
*.MID MIDI-Dateien (Musik) Typ: SEQUENCER
*.AVI Video für Windows
Typ: AVIVIDEO
Der Typ AVIVIDEO kann nur abgespielt werden, wenn Sie die "Microsoft Video for
Windows"-Runtime installiert haben.
Wenn Sie den Treiber für Autodesk-Animationen installiert haben, kommt noch ein Typ
hinzu:
*.FLC/*.FLI Animationen
Typ: ANIMATION1
Für weitere interessante MCI-Befehle muß ich auch hier wieder auf die Einführung zu
PROFAN² verweisen. Alle MCI-Befehle zu beschreiben würde den Rahmen dieses Artikels
bei Weitem sprengen.
MEDIEN-PLAYER IN PROFAN²
Den Abschluß dieses Exkurses in die Multimediaprogrammierung bildet ein kompletter
Medienspieler in PROFAN². Gewiß, in der vorliegenden Form kann er nicht mehr als der
Medienspieler von Windows, dafür können Sie ihn aber beliebig ändern und erweitern.
Listing: MEDITPLAY.PRF
Declare Text$,Maske$,Ende%,Antwort%
Proc SpieleAVI
Parameters Datei$
Declare MCI$
Print Datei$
If @Neq$(Datei$,"")
@MCISend$("CLOSE FILM")
Let MCI$=@Add$(@add$("OPEN ",Datei$)," TYPE AVIVIDEO ALIAS FILM")
Let MCI$=@MCISend$(MCI$)
If %MCIError
@MessageBox(MCI$,"Fehler:",16)
Else
@MCISend$("PLAY FILM")
EndIf
EndIf
EndProc
Seite 142
RGH-PROFAN²
Proc SpieleFilm
Parameters Datei$
Declare MCI$
Print Datei$
If @Neq$(Datei$,"")
@MCISend$("CLOSE FILM")
Let MCI$=@Add$(@add$("OPEN ",Datei$),\
" TYPE ANIMATION1 ALIAS FILM")
Let MCI$=@MCISend$(MCI$)
If %MCIError
@MessageBox(MCI$,"Fehler:",16)
Else
@MCISend$("PLAY FILM WAIT")
EndIf
EndIf
EndProc
Proc SpieleWave
Parameters Datei$
Declare MCI$
Print Datei$
If @Neq$(Datei$,"")
@MCISend$("CLOSE SOUND")
Let MCI$=@Add$(@add$("OPEN ",Datei$),\
" TYPE WAVEAUDIO ALIAS SOUND")
Let MCI$=@MCISend$(MCI$)
If %MCIError
@MessageBox(MCI$,"Fehler:",16)
Else
@MCISend$("PLAY SOUND")
EndIf
EndIf
EndProc
Proc SpieleMidi
Parameters Datei$
Declare MCI$
Print Datei$
If @Neq$(Datei$,"")
@MCISend$("CLOSE SOUND")
Let MCI$=@Add$(@add$("OPEN ",Datei$),\
" TYPE SEQUENCER ALIAS SOUND")
Let MCI$=@MCISend$(MCI$)
If %MCIError
@MessageBox(MCI$,"Fehler:",16)
Else
@MCISend$("PLAY SOUND")
EndIf
EndIf
EndProc
Seite 143
RGH-PROFAN²
Proc SpieleCD
Declare MCI$,TitelZahl%,I%
@MCISend$("CLOSE CD")
Let MCI$=@MCISend$("open cdaudio alias cd")
If %MCIError
@MessageBox(MCI$,"Fehler:",16)
Else
Let MCI$=@MCISend$("status cd length")
Print "Länge der CD: ";MCI$;
Let MCI$=@MCISend$("status cd number of tracks")
Print " - Titelzahl: ";MCI$
Let TitelZahl%=@Val(MCI$)
Let I%=1
CreateMenu
WhileNot @GT(I%,TitelZahl%)
AppendMenu I%,@Add$("Titel ",@Str$(I%))
Inc I%
Wend
TrackMenu 30,30
If %MenuItem
Print "Titel Nr: ";%MenuItem;" - Länge: ";
@MCISend$("SET CD TIME FORMAT TMSF")
Print @MCISend$(@Add$("STATUS CD LENGTH TRACK ",\
@Str$(%MenuItem)))
@MCISend$(@Add$("PLAY CD FROM ",@Str$(%MenuItem)))
EndIf
EndIf
EndProc
WindowStyle 8
Window 10,10-400,60
WindowTitle "RGH-Medien-Player in PROFAN"
Cls
PopUp "&Datei"
AppendMenu 11,"&Video für Windows"
AppendMenu 12,"&Animation (FLI)"
AppendMenu 13,"Animation (&FLC)"
Separator
AppendMenu 14,"&MIDI-Datei"
AppendMenu 15,"Sound-Datei (&WAV)"
Separator
AppendMenu 16,"&CD-Titel spielen"
Separator
AppendMenu 17,"&Ende"
AppendMenuBar 20,"&Info"
Seite 144
RGH-PROFAN²
WhileNot Ende%
WaitInput
Cls
If @MenuItem(11)
Print "Video für Windows"
SpieleAVI @LoadFile$("Video-Datei:","*.AVI")
ElseIf @MenuItem(12)
Print "FLI-Animation"
SpieleFilm @LoadFile$("FLI-Animation:","*.FLI")
ElseIf @MenuItem(13)
Print "FLC-Animation"
SpieleFilm @LoadFile$("FLC-Animation:","*.FLC")
ElseIf @MenuItem(14)
Print "Midi-Datei"
SpieleMidi @LoadFile$("Sound-Datei:","*.MID")
ElseIf @MenuItem(15)
Print "Sound-Datei"
SpieleWave @LoadFile$("Sound-Datei:","*.WAV")
ElseIf @MenuItem(16)
Print "Musik-CD"
SpieleCD
ElseIf @MenuItem(17)
Let Antwort%=@MessageBox("Wollen Sie den Medien-Spieler \
wirklich beenden?",
\
"Seien Sie ehrlich:",36)
Case @Equ(Antwort%,6):Let Ende% = 1
ElseIf @MenuItem(20)
@MessageBox("Der Mulimedia-Player von RGH","Info",64)
EndIf
Wend
@MCISend$("CLOSE FILM")
@MCISend$("CLOSE SOUND")
@MCISend$("CLOSE CD")
End
Der Medien-Player findet sich als "MEDIPLAY.PRF" im PROFAN²-Verzeichnis. Es kommt
nicht allzuviel Neues im Programm vor, deshalb will ich im Folgenden nur kurz auf die eine
oder andere Besonderheit eingehen:
Vor dem Hauptprogramm stehen 5 Prozeduren, die die eigentliche Arbeit tun. Jede Prozedur
in PROFAN² beginnt mit dem Befehl PROC und endet mit dem Befehl ENDPROC. Hinter
dem PROC steht der Name der Prozedur. Unter diesem Namen wird sie im Hauptprogramm
aufgerufen. Mit dem Befehl PARAMETERS übernehme ich Parameter, mit denen die
Prozedur aufgerufen wurde. In unserem Beispiel wird der Name der abzuspielenden Datei
als Parameter erwartet und in die Variable DATEI$ geschrieben. Alle Variablen die innerhalb
der Prozedur mit PARAMETERS oder DECLARE definiert werden, sind auch nur innerhalb
der Prozedur bekannt.
Sicherheitshalber wird zu Beginn jeder Prozedur das entsprechende Gerät geschlossen. Nur
so kann das gleiche Gerät während eines Programmlaufes mehrmals genutzt werden. Wurde
das Gerät noch nicht geöffnet, wird zwar %MCIError auf einen Wert ungleich 0 gesetzt. Da
wir diesen an dieser Stelle aber nicht abfragen ist das ohne Bedeutung.
Seite 145
RGH-PROFAN²
Eine Besonderheit gibt es beim Spielen der Musik-CD. Natürlich wird hier kein Dateiname
übergeben. Hingegen ermittelt die Prozedur zunächst die Anzahl der Titel der CD. Mit
CREATEMENU wird dann ein Pop-Up-Menü erzeugt. In der folgenden WHILE-Schleife wird
dann für jeden Titel ein Menüpunkt (mit APPENDMENU) hinzugefügt, der als Nummer die
Nummer des jeweiligen Titels und als Menüzeile das Wort "Titel " gefolgt von der Nummer
erhält. Mit TRACKMENU wird das erzeugte Menü dann an der angegebenen Position
angezeigt und auf eine Auswahl durch den Benutzer gewartet. Hat er einen Titel ausgewählt
(und das Menü nicht durch <Esc> oder Danebenklicken verlassen) steht in %MENUITEM die
Nummer des gewünschren Titels. Dieser wird angezeigt und gespielt.
Nach den Prozeduren beginnt das Hauptprogramm mit der Festlegung der Fensterart, der
Fenstergröße und des Fenstertitels. Als Nächstes wird das Menü der Anwendung erzeugt:
Mit POPUP wird ein Neues Menü hinzugefügt und mit APPENDMENÜ werden dem Menü
einzelne Punkte angehängt, die beim Anklicken von "Datei" aufklappen. Der SEPARATOR
steht für eine Trennlinie zwischen zwei Menüpunkten. Das "&" steht jeweils vor dem
Buchstaben, der im Menü unterrstrichen dargestellt ist und mittels dessen der Menüpunkt
auch per Tastatur ausgewählt werden kann. Mit APPENDMENUBAR wird dem Menü
schließlich noch der Menüpunkt "Info" hinzugefügt. "Info" steht zwar direkt neben "Datei",
aber es klappt sich dort kein Menü auf. "Info" ist ein eigener Menüpunkt mit eigener
Menünummer.
Nach der Definition des Menüs folgt die Hauptschleife des Programmes, die solange
durchlaufen wird, bis ENDE% einen Wert ungleich 0 aufweist. WAITINPUT wartet auf eine
Eingabe vom Anwender, auf eine Auswahl aus dem Menü. Je nach gewähltem Menüpunkt,
was mit der Funktion @MENUITEM abgefragt wird, wird die entsprechende Prozedur
aufgerufen. Über die Funktion @LOADFILES wird ein ausgewählter Dateiname an die
Prozedur übergeben.
Bei Programmende werden alle Geräte geschlossen. ACHTUNG: Die CD läuft aber weiter.
Soll diese bei Programmende auch anhalten, ist vor dem Befehl "CLOSE CD" der Befehl
"STOP CD" abzusenden.
Seite 146
RGH-PROFAN²
5 - Selbstdefinierte Dialoge
Ab PROFAN² 3.0 gibt es frei definierbare Dialogboxen. Diese gibt es in zwei Ausprägungen:
Einmal als Dialogbox mit fester Fenstergröße (@CREATEDIALOG) und zum zweiten als
Dialogfenster (@CREATEWINDOW), dessen Stil mit WINDOWSTYLE eingestellt werden
kann. In beiden Fällen handelt es sich um nichtmodale Fenster, d.h.: Wenn der Anwender
außerhalb des Dialoges etwas anklickt, kann die Anwendung darauf reagieren. Soll der
Anwender nichts anderes machen können, bevor der Dialog abgearbeitet ist muß das
Programm (will heißen: Sie als Programmierer) dafür Sorge tragen, daß nur auf Ereignisse
des Dialoges reagiert wird. Normalerweise wird man für jeden Dialog eine eigene Prozedur
schreiben, die erst dann verlassen wird, wenn der Dialog beendet ist.
Mit dem Dialoghelfer lassen sich komplette Dialogboxen sehr rasch realisieren. In diesem
Kursteil werden wir ihn jedoch einmal beiseite lassen und Dialoge "zu Fuß" programmieren.
Das Verständnis der Programmierung von Dialogboxen ohne Helfer ist eine unverzichtbare
Hilfe beim Anpassen der vom Helfer erzeugten Programmgerüste!
Ein erster minimalistischer Dialog
Um einen ersten Dialog zu programmieren schreiben wir ein Mini-Programm mit einem
kleinen Dialog. Das Programm hat nur ein Menü "Aktion" mit den beiden Menüpunkten
"Dialog 1" und "Ende". Der Dialog bietet nicht mehr, als einen OK-Button, bei dessen
Anklicken der Dialog beendet wird.
Listing: Dialog 1
Declare Ende%
PROC Dialog1
Declare hD%, hB%, OK%
'Dialogfenster erzeugen
Let hD% = @CreateDialog(%HWnd,"Dialogfenster",80,90,180,160)
'Einen Button mit OK erzeugen
Let hB% = @CreateButton(hD%,"&OK",120,100,40,25)
'Dialog-Schleife
Let OK% = 0
WhileNot Ok%
WaitInput
If @GetFocus(hB%) 'OK wurde angeklickt
Let Ok% = 1
EndIf
Wend
'Dialogfenster (incl. Button) entfernen
@DestroyWindow(hD%)
ENDPROC
Seite 147
RGH-PROFAN²
'Haupt-Programm
'-------------Window 20,20-400,300
PopUp "&Aktion"
AppendMenu 101,"&Dialog"
Separator
AppendMenu 199,"&Ende"
Let Ende% = 0
WhileNot Ende%
WaitInput
If @MenuItem(101)
Dialog1
ElseIf @MenuItem(199)
Let Ende% = 1
EndIf
Wend
End
Wie auch bei Menüs kann mit einem & der Hotkey, der unterstrichene Buchstabe markiert
werden. Dieses Fensterobjekt kann dann mit ALT und diesem Buchstaben angewählt werden
In unserem Beispielprogramm gehört das Dialogfenster zum PROFAN²- Hauptfenster
(%HWnd) und sein Handle wird in hD% gespeichert. Die Fensterobjekte des Dialoges
gehören zum Dialogfenster (hd%). Im Beispiel wird ein Button mit der Aufschrift "OK"
erzeugt und sein Handle in hB% gespeichert. Anschließend folgt die in PROFAN² übliche
WHILE-Schleife mit dem WAITINPUT. WAITINPUT wartet auf ein Ereignis.
Ein solches Ereignis ist z.B. das Anklicken eines Fensterobjektes oder das <Enter> in einem
Eingabefeld oder Drücken eines über TAB angewählten Buttons mit SPACE ...
Im Beispiel wird dann, wenn das Ereignis den "OK"-Button betrifft, die Variable OK% auf 1
gesetzt und damit die WHILE-Schleife verlassen. Vor Verlassen der Dialog-Prozedur wird
das Dialogfenster entfernt und mit ihm auch der OK-Button, da dieser ja in der
Fensterhierarchie ein dem Dialogfenster untergeordnetes Fenster war. Da die WHILESchleife nur dann verlassen wird, wenn OK angeklickt wurde, reagiert das Programm nicht
auf andere Ereignisse, wie z.B. Menüauswahl, bevor der Dialog beendet wird. Sollte unser
Programm z.B. auch auf das Beenden durch den Menüpunkt Ende reagieren, müßte das
Menüereignis auch in der Dialogschleife abgefragt und die Variable Ende% auf 1 gesetzt
werden. Diese Variante fügen wird als Dialog2 in unser Programm ein.
Seite 148
RGH-PROFAN²
PROC Dialog2
Declare hD%, hB%, OK%
'Dialogfenster erzeugen
Let hD% = @CreateDialog(%HWnd,"Dialogfenster",80,90,180,160)
'Einen Button mit OK erzeugen
Let hB% = @CreateButton(hD%,"&OK",120,100,40,25)
'Dialog-Schleife
Let OK% = 0
WhileNot Ok%
WaitInput
If @GetFocus(hB%) 'OK wurde angeklickt
Let Ok% = 1
ElseIf @MenuItem(199) 'Menüpunkt "Ende"
Let Ok% = 1
Let Ende% = 1
EndIf
Wend
'Dialogfenster (incl. Button) entfernen
@DestroyWindow(hD%)
ENDPROC
Ein Text in der Dialogbox ist manchmal angebracht
Hin und wieder ist es sinnvoll, Dialogboxen zum Anzeigen von kurzen Texten zu verwenden.
Wir wollen den Text "Ihre Festplatte wird formatiert!" anzeigen. Um in einer Dialogbox Text
anzuzeigen, verwenden wir die Funktion @CREATETEXT. Da der Text nur angezeigt wird,
benötigen wir sein Handle nicht, d.h. wir brauchen das Ergebnis keiner Variablen
zuzuweisen. Fügen wir unserem Programm also noch einen dritten Dialog hinzu.
PROC Dialog3
Declare hD%, hB%, OK%
Let hD% = @CreateDialog(%HWnd,"Dialogfenster 3",80,90,180,160)
Let hB% = @CreateButton(hD%,"&OK",120,100,40,25)
@CreateText(hD%,"Ihre Festplatte wird formatiert", \
20,5,140,50)
'Dialog-Schleife
Let OK% = 0
WhileNot Ok%
WaitInput
If @GetFocus(hB%) 'OK wurde angeklickt
Let Ok% = 1
EndIf
Wend
@DestroyWindow(hD%)
ENDPROC
Das Ergebnis ist ebenso beeindruckend wie erschreckend. Der Computer teilt mit, daß die
Festplatte formatiert wird, und läßt als Antwort lediglich OK% zu. (Keine Angst: Natürlich
formatiert das PROFAN²-Programm NICHT Ihre Festplatte. PROFAN² hat keinen Befehl, mit
dem dies möglich wäre.)
Die nächste Erweiterung wäre also ein zweiter Button, der Abbruch heißt. Natürlich soll auch
dieser Button den Dialog beenden. Während bei "Abbruch" nichts geschehen soll, wird bei
"OK" eine Aktion erfolgen. In unserem Beispiel wird "Ihre Festplatte wurde formatiert." in das
Hauptfenster geschrieben.
Seite 149
RGH-PROFAN²
PROC Dialog4
Declare hD%, hB%, hA%, OK%
Let hD% = @CreateDialog(%HWnd,"Dialogfenster 4",80,90,180,160)
Let hB% = @CreateButton(hD%,"&OK",10,100,40,25)
Let hA% = @CreateButton(hD%,"&Abbruch",100,100,60,25)
@CreateText(hD%,"Ihre Festplatte wird formatiert", \
20,5,140,50)
'Dialog-Schleife
Let OK% = 0
WhileNot Ok%
WaitInput
If @GetFocus(hA%)
'ABBRUCH wurde angeklickt
Let Ok% = 1
ElseIf @GetFocus(hB%) 'OK wurde angeklickt
Let Ok% = 1
Print "Die Festplatte wurde formatiert!"
EndIf
Wend
@DestroyWindow(hD%)
ENDPROC
Oftmals wird man eine solche Aktion aber erst nach dem Verlassen des Dialoges
durchführen wollen. In diesem Fall gibt es prinzipiell zwei Möglichkeiten: Zum einen kann
man eine Variable im Hauptprogramm deklarieren, der man dann je nach gedrücktem Button
einen Wert zuweist. Zum anderen kann man eine zusätzliche Variable in der Dialogroutine
deklarieren, deren Wert man direkt vor dem ENDPROC mittels RETURN <WERT> an das
Hauptprogramm übergibt. Siehe hierzu die entsprechenden Ausführungen in der Hilfedatei
(in der Referenz und dem Kapitel über Prozeduren).
Eingabefelder
Selbstverständlich sind auch normale Eingabefelder möglich. Ein Eingabefeld wird mit dem
Befehl @CREATEEDIT erzeugt. Das Ergebnis dieser Funktion ist wie immer das Handle des
Dialogelementes. Um nun herauszubekommen, welcher Text sich zu einem bestimmten
Zeitpunkt im Eingabefeld befindet, ist die Funktion @GETTEXT zu verwenden, der als
Parameter das Handle des Eingabefeldes übergeben wird. Diese Funktion ermittelt immer
den Text des Dialogelementes mit dem angegebenen Handle. (Das kann also auch das
Eingabefeld eines fremden Programmes sein, dessen Handle man mit %GETFOCUS
ermittelt hat.)
In einer Dialogbox oder Eingabemaske wird man den Inhalt der Eingabefelder nach dem
Drücken der "OK"-Taste abfragen und ihn dann entsprechenden Stringvariablen zuordnen. In
unserem Beispiel haben wir Eingabe-Felder für Name und Vorname.
Seite 150
RGH-PROFAN²
PROC Dialog5
Declare hD%, hB%, hA%, hV%, hN%, OK%, \
Name$, Vorname$
Let hD% = @CreateDialog(%HWnd,"Dialogfenster 5",80,90,180,160)
@CreateText(hD%,"Vorname:", 10, 8,60,20)
@CreateText(hD%,"Name:",
10,33,60,20)
Let hV% = @CreateEdit(hD%,"",75, 5,85,24)
Let hN% = @CreateEdit(hD%,"",75,30,85,24)
Let hB% = @CreateButton(hD%,"&OK",10,100,40,25)
Let hA% = @CreateButton(hD%,"&Abbruch",100,100,60,25)
'Dialog-Schleife
@SetFocus(hV%)
Let OK% = 0
WhileNot Ok%
WaitInput
If @Equ(%Key,2)
'Alt-F4 bzw. Schließen
Let Ok% = 1
ElseIf @GetFocus(hA%) 'ABBRUCH wurde angeklickt
Let Ok% = 1
Cls
Print "... abgebrochen ..."
ElseIf @GetFocus(hB%) 'OK wurde angeklickt
Let Ok% = 1
Let Name$
= @GetText$(hN%)
Let Vorname$ = @GetText$(hV%)
Cls
Print "Name: ";Vorname$,Name$
EndIf
Wend
@DestroyWindow(hD%)
ENDPROC
Bei den Eingabefeldern gibt es eine Besonderheit: Wenn der Parameter für die senkrechte
Ausdehnung des Eingabefeldes negativ ist, wird die Paßwortfunktion aktiviert. Eingegebene
Zeichen erscheinen als Sterne. Die Funktion @GETTEXT ermittelt trotzdem den
eingegebenen Text. Mit dem Befehl SETTEXT könnte man auch vom Programm aus ein
Eingabefeld mit einem Inhalt bestücken, wobei der erste Parameter der Funktion das Handle
ist und der zweite der Text. Im Falle einer Dialogbox oder eines Fensters, ändert SETTEXT
die Überschrift, bei Buttons und anderen Dialogelementen wird der entsprechende Text
geändert.
Um den Eingabekursor auf das erste Eingabefeld zu setzen, wird die Funktion @SETFOCUS
verwandt. Wichtig ist, daß die Eingabefelder direkt nacheinander folgen, damit der
Eingabekursor bei jedem Enter ein Feld weiter geht.
Eine weitere Sache soll nicht unerwähnt bleiben: Bei den bisherigen Dialogfenstern blieb der
Doppelklick auf das Systemmenü des Dialoges wirklungslos. Auch das Schließen über Alt-F4
bzw. den Menüpunkt "Schließen" funktionierte nicht. Im 5. Dialog ist dieses nun realisiert:
Wenn die Systemvariable %KEY den Wert 2 hat, wurde eine der genannten Aktionen
ausgeführt und ENDE% wird auf 1 gesetzt.
Seite 151
RGH-PROFAN²
Checkboxen, Radiobuttons und Icons
Checkboxen sind die kleinen Kästchen zum Ankreuzen. Mit @CREATECHECKBOX werden
sie erzeugt und mit @GETCHECK kann abgefragt werden, ob die Checkbox mit dem
entsprechenden Handle angekreuzt ist oder nicht. In unserem Beispiel kann angekreuzt
werden, ob der Name einem Kunden gehört oder nicht.
Ein weiteres wichtiges Element sind die Radiobuttons. Sie treten in der Regel in
Gruppenfeldern (neudeutsch: Groupboxen) auf und es kann in jeder Gruppe immer nur ein
Radiobutton markiert sein. Wird keine GROUPBOX (das ist der Rahmen um die Gruppe)
verwandt, gehören alle Radiobuttons eines Dialoges einer Gruppe an. Will man mehrere
Gruppen von Radiobuttons bilden, muß man erst die erste Groupbox mit
@CREATEGROUPBOX
erzeugen,
dann
die
entsprechen
Radiobuttons
mit
@CREATERADIOBUTTON, dann die zweite Groupbox und ihre Radionbuttons und so
weiter. Natürlich kann man Groupboxen auch ohne Radiobuttons zur Verschönerung des
Dialoges verwenden. Und wenn man keinen Text für die Groupbox angibt, erhält man ein
schlichtes Rechteck. Auch Radiobuttons werden mit @GETCHECK abgefragt und können
mit SETCHECK gesetzt werden.
Ein weiteres Dialogelement sind Icons. Alle in PROFAN² vorhandenen Icons können mit
@CREATEICON in einem Dialog plaziert werden. Als letztes Beispiel ein Dialog, der alle
bisher beschriebenen Elemente enthält.
Seite 152
RGH-PROFAN²
PROC Dialog6
Declare hD%, hB%, hA%, hV%, hN%, hK%, hGm%, hGw%, OK%, \
Name$, Vorname$
Let hD% = @CreateDialog(%HWnd,"Dialogfenster 6",80,90,180,200)
@CreateText(hD%,"Vorname:", 10, 8,60,20)
@CreateText(hD%,"Name:",
10,33,60,20)
@CreateIcon(hD%,"PROFAN", 125,90)
@CreateGroupBox(hD%,"Geschlecht",10,75,100,60)
Let hV% = @CreateEdit(hD%,"",75, 5,85,24)
Let hN% = @CreateEdit(hD%,"",75,30,85,24)
Let hk% = @CreateCheckBox(hD%,"Kunde",10,55,60,24)
Let hGw%= @CreateRadioButton(hD%,"weiblich",17, 93,80,20)
Let hGm%= @CreateRadioButton(hD%,"männlich",17,113,80,20)
Let hB% = @CreateButton(hD%,"&OK",10,140,40,25)
Let hA% = @CreateButton(hD%,"&Abbruch",100,140,60,25)
@SetFocus(hV%)
SetCheck hGw%,1
'"weiblich" ankreuzen
Let OK% = 0
WhileNot Ok%
WaitInput
If @Equ(%Key,2)
'Alt-F4 bzw. Schließen
Let Ok% = 1
ElseIf @GetFocus(hA%) 'ABBRUCH wurde angeklickt
Let Ok% = 1
Cls
Print "... abgebrochen ..."
ElseIf @GetFocus(hB%) 'OK wurde angeklickt
Let Ok% = 1
Let Name$
= @GetText$(hN%)
Let Vorname$ = @GetText$(hV%)
Cls
Print "Name: ";Vorname$,Name$
If @GetCheck(hGw%)
Print "weiblich ";
Else
Print "männlich ";
Endif
If @GetCheck(hK%)
Print "und Kunde!"
Else
Print "und noch nicht Kunde!"
Endif
EndIf
Wend
@DestroyWindow(hD%)
ENDPROC
Das Ganze fassen wir abschließend in ein Listing zusammen, welches am Ende dieses
Kapitels abgedruckt ist.
Der Vollständigkeit halber sei noch auf die weiteren Dialogelemente verwiesen, die
PROFAN² 6.0 unterstützt: Es gibt sortierte und unsortierte Listoxen, mehrzeilige Editierfelder
und Auswahlboxen, mit denen man aus einer Anzahl von Einträgen einen auswählen kann.
Da diese aber ähnlich programmiert werden, wie die hier beschrieben Dialogelemente, soll in
diesem Kursteil nicht näher darauf eingegangen werden. Ausführliche Hinweise finden sich
im entsprechenden Kapitel der Einführung und in der Referenz!
Seite 153
RGH-PROFAN²
Noch ein wichtiger Hinweis
In einem Dialog können Bildschirmelemente nur mit @CREATE... erzeugt werden. Alle
anderen Ausgabebefehle, wie z.B. DRAWTEXT, PRINT oder die ganzen Grafikbefehle,
wirken immer nur auf das Hauptfenster des PROFAN²-Programmes. Künftige PROFAN²Versionen werden hier möglicherweise flexibler sein.
Seite 154
RGH-PROFAN²
Listing: DIALOGE.PRF
Declare Ende%
PROC Dialog1
Declare hD%, hB%, OK%
'Dialogfenster erzeugen
Let hD% = @CreateDialog(%HWnd,"Dialogfenster",80,90,180,160)
'Einen Button mit OK erzeugen
Let hB% = @CreateButton(hD%,"&OK",120,100,40,25)
'Dialog-Schleife
Let OK% = 0
WhileNot Ok%
WaitInput
If @GetFocus(hB%) 'OK wurde angeklickt
Let Ok% = 1
EndIf
Wend
'Dialogfenster (incl. Button) entfernen
@DestroyWindow(hD%)
ENDPROC
PROC Dialog2
Declare hD%, hB%, OK%
'Dialogfenster erzeugen
Let hD% = @CreateDialog(%HWnd,"Dialogfenster",80,90,180,160)
'Einen Button mit OK erzeugen
Let hB% = @CreateButton(hD%,"&OK",120,100,40,25)
'Dialog-Schleife
Let OK% = 0
WhileNot Ok%
WaitInput
If @GetFocus(hB%) 'OK wurde angeklickt
Let Ok% = 1
ElseIf @MenuItem(199) 'Menüpunkt "Ende"
Let Ok% = 1
Let Ende% = 1
EndIf
Wend
'Dialogfenster (incl. Button) entfernen
@DestroyWindow(hD%)
ENDPROC
PROC Dialog3
Declare hD%, hB%, OK%
Let hD% = @CreateDialog(%HWnd,"Dialogfenster 3",80,90,180,160)
Let hB% = @CreateButton(hD%,"&OK",120,100,40,25)
@CreateText(hD%,"Ihre Festplatte wird formatiert", \
20,5,140,50)
'Dialog-Schleife
Let OK% = 0
WhileNot Ok%
WaitInput
If @GetFocus(hB%) 'OK wurde angeklickt
Let Ok% = 1
EndIf
Wend
@DestroyWindow(hD%)
ENDPROC
Seite 155
RGH-PROFAN²
PROC Dialog4
Declare hD%, hB%, hA%, OK%
Let hD% = @CreateDialog(%HWnd,"Dialogfenster 4",80,90,180,160)
Let hB% = @CreateButton(hD%,"&OK",10,100,40,25)
Let hA% = @CreateButton(hD%,"&Abbruch",100,100,60,25)
@CreateText(hD%,"Ihre Festplatte wird formatiert", \
20,5,140,50)
'Dialog-Schleife
Let OK% = 0
WhileNot Ok%
WaitInput
If @GetFocus(hA%)
'ABBRUCH wurde angeklickt
Let Ok% = 1
ElseIf @GetFocus(hB%) 'OK wurde angeklickt
Let Ok% = 1
Print "Die Festplatte wurde formatiert!"
EndIf
Wend
@DestroyWindow(hD%)
ENDPROC
PROC Dialog5
Declare hD%, hB%, hA%, hV%, hN%, OK%, \
Name$, Vorname$
Let hD% = @CreateDialog(%HWnd,"Dialogfenster 5",80,90,180,160)
@CreateText(hD%,"Vorname:", 10, 8,60,20)
@CreateText(hD%,"Name:",
10,33,60,20)
Let hV% = @CreateEdit(hD%,"",75, 5,85,24)
Let hN% = @CreateEdit(hD%,"",75,30,85,24)
Let hB% = @CreateButton(hD%,"&OK",10,100,40,25)
Let hA% = @CreateButton(hD%,"&Abbruch",100,100,60,25)
'Dialog-Schleife
@SetFocus(hV%)
Let OK% = 0
WhileNot Ok%
WaitInput
If @Equ(%Key,2)
'Alt-F4 bzw. Schließen
Let Ok% = 1
ElseIf @GetFocus(hA%) 'ABBRUCH wurde angeklickt
Let Ok% = 1
Cls
Print "... abgebrochen ..."
ElseIf @GetFocus(hB%) 'OK wurde angeklickt
Let Ok% = 1
Let Name$
= @GetText$(hN%)
Let Vorname$ = @GetText$(hV%)
Cls
Print "Name: ";Vorname$,Name$
EndIf
Wend
@DestroyWindow(hD%)
ENDPROC
Seite 156
RGH-PROFAN²
PROC Dialog6
Declare hD%, hB%, hA%, hV%, hN%, hK%, hGm%, hGw%, OK%, \
Name$, Vorname$
Let hD% = @CreateDialog(%HWnd,"Dialogfenster 6",80,90,180,200)
@CreateText(hD%,"Vorname:", 10, 8,60,20)
@CreateText(hD%,"Name:",
10,33,60,20)
@CreateIcon(hD%,"PROFAN", 125,90)
@CreateGroupBox(hD%,"Geschlecht",10,75,100,60)
Let hV% = @CreateEdit(hD%,"",75, 5,85,24)
Let hN% = @CreateEdit(hD%,"",75,30,85,24)
Let hk% = @CreateCheckBox(hD%,"Kunde",10,55,60,24)
Let hGw%= @CreateRadioButton(hD%,"weiblich",17, 93,80,20)
Let hGm%= @CreateRadioButton(hD%,"männlich",17,113,80,20)
Let hB% = @CreateButton(hD%,"&OK",10,140,40,25)
Let hA% = @CreateButton(hD%,"&Abbruch",100,140,60,25)
@SetFocus(hV%)
SetCheck hGw%,1
'"weiblich" ankreuzen
Let OK% = 0
WhileNot Ok%
WaitInput
If @Equ(%Key,2)
'Alt-F4 bzw. Schließen
Let Ok% = 1
ElseIf @GetFocus(hA%) 'ABBRUCH wurde angeklickt
Let Ok% = 1
Cls
Print "... abgebrochen ..."
ElseIf @GetFocus(hB%) 'OK wurde angeklickt
Let Ok% = 1
Let Name$
= @GetText$(hN%)
Let Vorname$ = @GetText$(hV%)
Cls
Print "Name: ";Vorname$,Name$
If @GetCheck(hGw%)
Print "weiblich ";
Else
Print "männlich ";
Endif
If @GetCheck(hK%)
Print "und Kunde!"
Else
Print "und noch nicht Kunde!"
Endif
EndIf
Wend
@DestroyWindow(hD%)
ENDPROC
'Haupt-Programm
'-------------Window 20,20-400,300
PopUp "&Aktion"
AppendMenu 101,"Dialog
AppendMenu 102,"Dialog
AppendMenu 103,"Dialog
AppendMenu 104,"Dialog
AppendMenu 105,"Dialog
AppendMenu 106,"Dialog
Separator
AppendMenu 199,"&Ende"
&1"
&2"
&3"
&4"
&5"
&6"
Seite 157
RGH-PROFAN²
Let Ende% = 0
WhileNot Ende%
WaitInput
If @MenuItem(101)
Dialog1
ElseIf @MenuItem(102)
Dialog2
ElseIf @MenuItem(103)
Dialog3
ElseIf @MenuItem(104)
Dialog4
ElseIf @MenuItem(105)
Dialog5
ElseIf @MenuItem(106)
Dialog6
ElseIf @MenuItem(199)
Let Ende% = 1
EndIf
Wend
End
Seite 158
RGH-PROFAN²
Programmieren für Anwender
P R O F A N ² 6.0
DIE einfache Programmiersprache
für Windows 3.x und Windows 95
Teil 3: Referenz
Seite 159
RGH-PROFAN²
Übersicht Systemvariablen
!Input
$dbLUpdate
$dbFName
$dbFType
$DosVer
$Drive
$GetInput
$GetText
$Input
$ProfVer
$SysPath
$WinPath
$WinVer
%BitsPixel
%BmpX
%BmpY
%Button
%dbDeleted
%dbEoF
%dbFCount
%dbFDecs
%dbFLen
%dbFNumber
%dbHeader
%dbMemo
%dbRecSize
%dbVersion
%DDEWin
%Desktop
%Error
%ErrNumber
%Font
%GetCount
%GetCurSel
%GetFocus
%GetInputState
%HDC
%HDC2
%HINstance
%HWnd
%Input
%IOResult
%Key
%LFN
%MaxX
%MaxY
%MCIError
%MenuItem
%Message
%MouseKey
%MousePressed
%MouseX
%MouseY
%MWnd (siehe %Message)
%ParCount
%PCount
Seite 160
RGH-PROFAN²
%PeekMessage
%ScanKey
%wmPaint
%wmTimer
%Win32
%WinTop
%WinBottom
%WinRight
%WinLeft
&BmpCol
&dbRecCount
&dbRecNo
&GetTickCount
&Input
&LParam (siehe %Message)
&SQLCount
&WParam (siehe %Message)
Seite 161
RGH-PROFAN²
Übersicht Funktionen
@!
@$
@%
@&
@Abs
@Add$
@Add
@AddChoice
@AddString
@And
@AnsiToOem$
@ArcTan
@BlockRead
@Bin$
@Byte
@Char$
@ChooseDir$
@Chr$
@CloseCom
@ComError
@Control
@Cos
@Cot
@CreateButton
@CreateCheckBox
@CreateChoiceBox
@CreateDefButton
@CreateDialog
@CreateEdit
@CreateExtDialog
@CreateGroupBox
@CreateHScroll
@CreateIcon
@CreateListBox
@CreateMultiEdit
@CreateRadioButton
@CreateText
@CreateSortedListBox
@CreateVScroll
@CreateWindow
@CToD$
@Date$
@dbAppendBlank
@dbClose
@dbDelete
@dbFind
@dbGet$
@dbGetField$
@dbGetMemo
@dbGo
@dbIndex
@dbOpen
@dbPack
@dbPut
Seite 162
RGH-PROFAN²
@dbPutField
@dbPutMemo
@dbPutRec
@dbSeek
@dbUndelete
@dbUse
@Del$
@DeleteChoice
@DeleteString
@DestroyWindow
@DiskFree
@DiskSize
@Div&
@Div
@DToC$
@EditBox
@Eof
@Equ$
@Equ
@Exp
@ExtString$
@FilePos
@FileSize
@FindFirst$
@FindNext$
@FindWindow
@Format$
@GetActiveWindow
@GetBValue
@GetByte
@GetCheck
@GetClip$
@GetCount
@GetCurSel
@GetDir$
@GetEnv$
@GetFAttr
@GetFDate$
@GetFileSize
@GetFocus
@GetGValue
@GetHandle
@GetKey$
@GetLine$
@GetLineCount
@GetPixel
@GetRValue
@GetString$
@GetText$
@GetUsage
@GT
@GT$
@Height
@Hex$ (siehe @Bin$)
Seite 163
RGH-PROFAN²
@IconCount
@If
@Inkey$
@Inp
@InpB
@Input$
@Ins$
@InsertString
@InStr
@Int
@KeyIn
@Left$
@Len
@Lg
@List!
@List$
@List%
@List&
@ListBox$
@ListBoxItem$
@Ln
@LoadFile$
@Long
@LongName$
@Lower$
@LT
@LT$
@MCISend$
@MenuItem
@MessageBox
@Mid$
@MkStr$
@Mod
@Mouse
@MoveListToChoice
@MoveListToEdit
@MoveListToList
@Mul
@NEq
@NEq$
@Not
@Oct$ (siehe @Bin$)
@OemToAnsi$
@Or
@Ord
@OpenCom
@Par$
@Pi
@Pow
@PostMessage
@Pwd$
Seite 164
RGH-PROFAN²
@ReadCom
@ReadIni$
@Right$
@RGB
@Rnd
@Round
@SaveFile$
@ScanKey
@SelectString
@SendKey
@SendMessage
@SendString
@SetActiveWindow
@SetBit
@SetCom
@SetComExt
@SetFocus
@ShortName$
@ShowWindow
@Sin
@Space$
@SQLInit
@Sqr
@Sqrt
@Str$
@String$
@Sub
@SubStr$
@Tan
@TestBit
@Time$
@TMouse
@Translate$
@Trim$
@Upper$
@UseDLL
@Val
@Width
@WinExec
@WinExecWait
@Word
@WriteCom
@XOr
Seite 165
RGH-PROFAN²
Übersicht Befehle
´(Apostroph)
Add
AddFiles
AddFonts
AddString
AddWindows
Append
AppendMenu
AppendMenuBar
Arc
Assign
Beep
BlockWrite
Byte
Case
CaseNot
Char
CharSet
CheckMenu
ChDir
Chord
ClearClip
ClearList
ClipLoadBMP
Close
CloseRW
Cls
Color
Copy
CopyBmp
CopyBmpToMem
CopySizedBmp
CreateMenu
DbCreate
DbCreateIndex
DDELink
DDEExecute
DDETerminate
Dec
Decimals
Declare
Def
Dim
Dim!
Dim$
Dim%
Dim&
Dispose
Seite 166
RGH-PROFAN²
DrawIcon
DrawExtBmp
DrawExtIcon
DrawLibIcon
DrawSizedExtBmp
DrawSysIcon
DrawText
Ellipse
Else
ElseIf
EnableMenu
EnableWindow
EndIf
End
EndPaint
EndPrint
EndProc
EndSub
EndWhile
Erase
ExitWindows
FileMode
Fill
Font
FreeDLL
GetMessage
GoSub ... Return
GoTo
If ... ElseIf ... Else ... EndIf
IfNot ... Else ... EndIf
Inc
Input
Input#
InsertMenu
KillTimer
Let
Line
LineTo
ListBoxItem$
List!
List$
List%
List&
LoadBmp
LoadSizedBmp
Locate
Long
MCLS
MCopyBmp
MCopySizedBmp
MessageBox
MkDir
MoveTo
Seite 167
RGH-PROFAN²
Music
Seite 168
RGH-PROFAN²
NextPage
NumWidth
Orientation
OpenRW
OutP
OutPB
Parameters
PassWord
Pie
Play
PlaySound
PopUp
Print
Print#
Proc ... EndProc
PutByte
PutClip
Randomize
ReadText
Rectangle
Rem
RemoveMenu
Rename
RePaint
Reset
Return
Rewrite
RmDir
RoundRect
Run
SaveBmp
SaveBmpToClip
ScreenCopy
Seek
Separator
SetAutoPaint
SetCheck
SetDialogFont
SetErrorLevel
SetFAttr
SetLFN
SetMenuItem
SetPixel
SetScrollPos
SetScrollRange
SetText
SetTimer ... KillTimer
SetTrueColor
SetWindowPos
Shell
Seite 169
RGH-PROFAN²
ShowCursor
ShowMin
ShowMax
ShowNormal
Sound
String
SQLDone
SQLExec
SQLSetNull
SQLSetDel
StartPaint ... EndPaint
StartPrint ... EndPrint
String
StrWidth
Sub
SubPopUp
TBox
TextColor
TraceOn
TraceOff
TrackMenu
UseBrush
UseCursor
UseExtCursur
UseExtMenu
UseFont
UseIcon
UsePen
WaitInput
WaitKey
WaitMouse
WaitScan
While ... EndWhile
WhileNot ... EndWhile
WinCopy
Window
WindowStyle
WindowTitle
WinHelp
Word
WriteIni
Seite 170
RGH-PROFAN²
1. Systemvariablen
Systemvariablen geben Auskunft über Zustände des Systems, z.B. die aktuelle Position der
Maus, das aktuelle Laufwerk, etc.
Es gibt vier Typen von Systemvariablen:
$Name
%Name
&Name
!Name
- Der Ergebnistyp ist ein String
- Der Ergebnistyp ist ein Integer
- Der Ergebnistyp ist ein LongInt
- Der Ergebnistyp ist ein Float
Seite 171
RGH-PROFAN²
!Input
Der zuletzt mit Input eingegebene Float-Wert.
Seite 172
RGH-PROFAN²
$dbFName
Name des aktuellen Feldes. Dieser enthält nur Großbuchstaben und den Unterstrich und
maximal 10 Zeichen.
$dbFType
Typ des aktuellen Datenbank-Feldes:
C = Character (String)
N = Numerisch
L = Logisch
M = Memo
D = Datum
$dbLUpdate
Datum der letzen Änderung der Datenbanktabelle in der Form TT.MM.JJ
$DOSVer
ermittelt die DOS-Version (z.B. "5.0" )
$Drive
Das aktuelle Laufwerk (ohne Pfadangabe).
$GetInput
Der zuletzt mit der Funktion @Input$ eingegebene Text.
$GetText
Der zuletzt in einer Listbox (Funktion @ListBox$) ausgewählte Text.
$Input
Der zuletzt mit Input eingegebene String.
$ProfVer
Die aktuelle PROFAN²-Version in der Form "X.YY-ZZ". Dabei steht X für die
Hauptversionsnummer, YY für die Unterversionsnummer und ZZ für die Bitzahl (16 =
Windows 3.x- Version / 32 = Windows95/NT-Version).
Für Version 5.0 für Windows 3.x wäre das Ergebnis z.B. "5.0-16", eine möglicherweise
kommende Version 5.1a für Windows95 hätte das Kennzeichen "5.1a-32".
Seite 173
RGH-PROFAN²
$SysPath
Windows-System-Pfad (z.B. "C:\WINDOWS\SYSTEM" )
$WinPath
Windows-Pfad (z.B. "C:\WINDOWS" )
$WinVer
ermittelt die Windows-Version (z.B. "3.10")
Seite 174
RGH-PROFAN²
%BmpX
Breite des zuletzt geladenen oder gespeicherten
LOADSIZEDBMP, MLOADBMP, SAVEBMP)
Bildes.
(nach
LOADBMP,
%BmpY
Höhe des zuletzt geladenen oder gespeicherten Bildes.
%BitsPixel
Die Farbauflösung des aktuellen Bildschirmtreibers in Bits pro Pixel:
1 = 2 Farben
4 = 16 Farben
8 = 256 Farben
16 = 64k Farben (HighColor)
24 = 16M Farben (TrueColor)
%Button
Der in einer MessageBox oder einem der vordefinierten Dialoge gedrückte Knopf:
1234567-
OK
Abbrechen (Cancel)
Abbrechen (Abort)
Wiederholen
Ignorieren
Ja
Nein
Bei vordefinierten Dialogen wird entweder 1 für "OK" oder 2 für "Abbrechen" zurückgegeben.
%dbDeleted
Löschkennzeichen des aktuellen Datensatzes:
1 = Datensatz ist als gelöscht gekennzeichnet.
0 = Datensatz ist nicht als gelöscht gekennzeichnet.
%dbEoF
End-Of-File-Kennzeichen der aktiven Datenbanktabelle:
1 = Ende der Datenbanktabelle ist erreicht.
0 = ... ist noch nicht erreicht
Seite 175
RGH-PROFAN²
%dbFCount
Zahl der Felder eines Satzes in der aktuellen Datenbank.
%dbFDecs
Dezimalstellen des aktuellen Datenbank-Feldes. Dieser Wert ist nur bei numerischen Feldern
von Bedeutung.
%dbFLen
Länge des aktuellen Feldes. Bei numerischen Feldern zählt hier auch der Dezimalpunkt mit.
Um zum Beispiel einen sechstelligen DM-Betrag mit zwei Nachkommastellen darzustellen,
muß das Feld eine Länge von 9 haben.
%dbFNumber
Nummer des aktuellen Feldes.
%dbHeader
Länge des Headers der aktiven Datenbanktabelle.
%dbMemo
Gibt an, ob die geöffnete dBase-Tabelle Memofelder enthält. PROFAN² unterstützt nur das
Memo- Format von dBase-III.
%dbRecSize
Länge eines Datensatzes der aktiven Datenbankabelle.
%DDEWin
Die Systemvariable enthält das Handle des DDE-Servers, wenn eine DDE-Verbindung
erfolgreich aufgebaut wurde, ansonsten enthält sie 0. Sollte der DDE-Server während der
Verbindung jedoch beendet werden, ändert die Systemvariable Ihren Wert nicht. Erst nach
DDETERMINATE wird sie wieder auf 0 gesetzt.
%DeskTop
Handle des Hintergrundfensters.
Seite 176
RGH-PROFAN²
%Error
Der zuletzt aufgetretene Fehlercode. Wie %IOResult wird %Error beim Auslesen wieder auf
0 gesetzt. Die Error-Werte:
012-
kein Fehler
Warnung
Fehler
%ErrNumber
enthält die Nummer des zuletzt aufgetretenen Fehlers. Beim Auslesen wird %ERRNUMBER
auf 0 zurückgesetzt.
%Font
Diese Systemvariable enthält ein Handle auf die mit USEFONT eingestellte Schrift. Kann
verwendet werden, um mittels einer Message die Schrift eines Fensterelementes (Button,
Liste, etc.) zu verändern.
%GetCount
Die Nummer des letzten Eintrags in der ListBox-Liste.
ACHTUNG: Da der erste Eintrag die Nummer 0 hat, ist die tatsächliche Anzahl der Einträge
um 1 höher!
Beispiel:
ClearList
AddFiles "C:\WINDOWS\*.EXE"
Print @add(%GetCount,1);" EXE-Dateien"
%GetCurSel
Nummer des in einer Listbox gewählten Eintrages.
%GetFocus
Handle des Fensterobjektes, das gerade aktiv ist. Im Gegensatz zu @GetActiveWindow()
ermittelt %GetFocus das Handle des gerade aktiven Buttons, der aktiven Liste, des aktiven
Editierfeldes, ... @GetActiveWindow() ermittelt das Handle des aktiven (Haupt)Fensters
Wurde während eines WAITINPUT F1 gedrückt, während der Fokus in einer Dialogbox bzw.
auf einem Diologelement ist, steht in %GetFocus der negative wert des Handles.
Siehe auch: @GetFocus
%GetInputState
Augenblicklicher Eingabestatus: Wenn innerhalb der Anwendung ein Tastendruck oder eine
Mausbewegung erfolgt, ist das Ergebnis <> 0!
Notwendig ist diese Systemvariable bei der Programmierung von Bildschirmschonern.
Siehe auch: %MousePressed
Seite 177
RGH-PROFAN²
Seite 178
RGH-PROFAN²
%HDC
Display-Context des Hauptfensters. Diese Systemvariable ist dann von Nutzen, wenn APIFunktionen aufrufen, die diesen Wert benötigen.
%HDC2
Display-Context der Hauptfensterkopie (Diese enthält immer eine exakte Kopie des Fensters,
um dieses bei Bedarf wieder neu aufzubauen.)
%HInstance
Das Instanz-Handle des aktuell laufenden PROFAN²-Programmes. Dieser Wert wird für
diejenigen Funktionen und Befehle benötigt, die das Instanz-Handle eines Programmes
benötigen, um auf dessen Resourcen zuzugreifen. Das Instanz-Handle anderer Programme
ist der Rückgabewert von @WinExec bzw. @UseDLL. Mittels %HInstance kann auf die
Resourcen (Strings, Icons, Bitmaps, Dialoge) des laufenden Programmes zugegriffen
werden. Beispiel:
Let Dlg% = @CreateExtDialog(%HInstance,%HWnd,"FileOpen")
Hier wird der Dialog zum Laden einer Datei aus dem laufenden Programm angezeigt. (Im
Interpreter ist dies PROFAN.EXE, beim fertigen zur EXE-Datei gelinkten Programm das
Programm selbst.) Da z.B. mit dem "Resource Workshop" von Borland (vor dem Linken!) der
PROFRUN.EXE Resourcen hinzugefügt, bzw. die bestehenden verändert werden können,
eröffnen sich hier ungeahnte Möglichkeiten.
Mit @GetUsage(%HInstance) kann ermittelt werden, wie oft ein Programm schon gestartet
wurde. Folgende Zeilen am Anfang eines Programmes verhindern dessen Mehrfachstart:
IF @Gt(@GetUsage(%HInstance),1)
@MessageBox("Das Programm läuft bereits!","INFO",0)
END
ENDIF
ACHTUNG: Die Funktion @GetUsage (entsprechend der API-Funktion GetModuleUsage)
gibt es aus Gründen, die nur Microsoft kennt, nur im 16-Bit-Windows. Im 32-Bit-PROFAN²
wird mittels eines Tricks diese 16-Bit-Funktion aufgerufen, da das 16-Bit-Windows in
Windows 95 nahezu komplett enthalten ist. Unter Windows NT dürfte die Funktion eine
Fehlermeldung erzeugen.
%HWnd
Handle des Hauptfensters eines PROFAN²-Programmes.
%Input
Der zuletzt mit Input eingegebene Integer-Wert.
Seite 179
RGH-PROFAN²
%IOResult
Nach einer Dateioperation oder einer Directory-Suche enthält diese Variable den
entsprechenden Wert:
Die Werte entsprechenden den von Turbo-Pascal her bekannten Ergebnissen:
023512 15 16 17 18 100 101 102 103 104 105 106 -
kein Fehler aufgetreten
Datei nicht gefunden
Pfad nicht gefunden
Zugriff verweigert (ReadOnly?)
Ungültiger Dateimodus
Laufwerksnummer unzuzulässig
Verzeichnis kann nicht gelöscht werden (noch Dateien drin?)
RENAME nicht über Laufwerksgrenzen möglich (siehe Rename)
Kein weiterer Eintrag (bei @FindFirst/@FindNext)
Lesefehler von Diskette/Platte
Schreibfehler auf Diskette/Platte
Dateinummer ist keiner Datei mit ASSIGN zugeordnet (siehe Assign)
Datei nicht offen (Reset, Rewrite oder Append fehlt)
Datei nicht zum Lesen geöffnet (Reset fehlt)
Datei nicht zum Schreiben geöffnet (Rewrite oder Append fehlt)
Falsches Format (bei Input #N,..)
%Key
Der ANSI-Code der zuletzt gedrückten Taste. Anwendung nach den Befehlen WAITKEY und
WAITINPUT:
WaitInput
If @Equ(Key,90)
Print "Du hast 'Z' gedrückt"
EndIf
Außer auf Tastendrücken reagiert WAITKEY wie auch WAITINPUT noch auf folgende
Ereignisse und bestückt %Key entsprechend:
1
2
4
5
13
255
Es wurde ein Eintrag in einer Listbox angewählt oder es wurde ein Eintrag einer
Auswahlbox gewählt
Es wurde in einer Dialogbox bzw. einem Dialogfenster auf das Systemmenü
doppelgeklickt, bzw. "Schließen" ausgewählt
Ein Fenster des Programmes wurde in der Größe verändert
Es wurde F1 gedrückt, während der Fokus auf einem Dialogelement bzw. in einer
Dialogbox war
Es wurde in einem einzeiligen Editierfeld oder einer Listbox <Enter> gedrückt
Es wurde ein Button, eine Checkbox oder ein Radiobutton angeklickt
%LFN
Die Systemvariable gibt an, ob lange Dateinamen verwandt werden. Normalerweise ermittelt
die Systemvariable automatisch, ob Windows 95 (%LFN = 1) oder Windows 3.1 (%LFN = 0)
genutzt wird. Sie kann allerdings durch SetLFN gesetzt werden.
HINWEIS: In der 32-Bit-Version hat die Systemvariable immer den Wert 1!
Seite 180
RGH-PROFAN²
%MaxX
Horizontale Auflösung des Bildschirmes.
%MaxY
Vertikale Auflösung des Bildschirmes.
%MCIError
Der zuletzt gemeldete Fehler beim Senden eines MCI-Strings zur Ansteuerung eines MultiMedia-Treibers (etwa CD, Soundkarte, MIDI-Gerät, etc.). Aussagekräftiger sind allerdings die
von @MCISend$ zurückgelieferten Fehlermeldungen (in der Landessprache).
%MenuItem
Die Identifikationsnummer des zuletzt angewählten Menüpunktes. Wurde das CopyrightZeichen angeklickt, ist die Nummer 254, wurde kein Menüpunkt angeklickt ist sie 0. Die
Nummern 1 .. 253 und 256 - 32766 können vom Programmierer verwandt werden. (255 und
32767 sind ohne Wirkung.)
%Message - &WParam - &LParam - %MWnd
Die Nummer der letzten aufgetretenen Message. Diese Systemvariable ist insbesondere in
Zusammenhang mit dem Befehl GETMESSAGE und der Systemvariablen
%PEEKMESSAGE sinnvoll, aber auch nach anderen WAIT-Befehlen oder gar in Schleifen
ohne einen der genannten Befehle sinnvoll. Etwaige meldungsspezifische Daten finden sich
in den Systemvariablen &LPARAM und &WPARAM, das Fenster für das die Message
bestimmt ist in %MWND.
%MouseKey
Die zuletzt gedrückte Maustaste:
012-
keine Taste gedrückt
linke Maustaste
rechte Maustaste
Die Position der Maus findet sich in %MouseX und %MouseY.
%MousePressed
Gibt an, welche Taste augenblicklich gedrückt wird. Wird durch Abfrage nicht zurückgesetzt.
Ergebnis: Siehe bei %MOUSEKEY
%MouseX
Die aktuelle X-Position der Maus.
%MouseY
Seite 181
RGH-PROFAN²
Die aktuelle Y-Position der Maus. Anwendung besonders nach den Befehlen WAITMOUSE
und WAITINPUT.
Seite 182
RGH-PROFAN²
%ParCount
Die Anzahl der beim Programmaufruf übergebenen Kommandozeilen-Parameter.
Parameter 0 ist beim Interpreter der Interpreter selber, bei der Runtime das Runtime-Modul
und bei einer EXE-Datei die EXE-Datei. Parameter 1 ist bei Interpreter und Runtime das
damit ausgeführte Programm. Weitere Hinweise siehe unter @PAR$.
%PCount
Gibt in die Anzahl der übergebenen Parameter des letzten Prozeduraufrufes wieder. Das ist
dann nützlich, wenn man eine Prozedur schreibt, die mit einer variablen Anzahl von
Parametern aufgerufen werden kann. Die Abfrage der Systemvariablen sollte möglichst am
Anfang der Prozedur stehen.
%PeekMessage
Diese Systemvariable gibt an, ob eine Message anliegt. Wenn nicht, ist das Ergebnis 0,
wenn ja werden die Systemvariblen %Message, &WParam, &LParam und %MWnd
entsprechend gefüllt. Die Message wird nur gelesen, nicht aber aus der Messageschlange
entfernt. Hierzu wäre der Befehl GETMESSAGE zu verwenden.
%ScanKey
Der Scancode (virtueller Code) der zuletzt gedrückten Taste. Wichtige Scancodes:
16 17 27 33 34 35 36 37 38 39 40 45 46 112 ... 123 -
Shift
Strg
Esc
BildHoch
BildRunter
Ende
Pos1
Links
Hoch
Rechts
Runter
Einfg
Entf
F1
...
F12
%Win32
Diese Systemvariable ist bei PROFAN² für 16 Bit auf 0 gesetzt und bei PROFAN² für
Windows 95 oder NT auf 1. Mit %Win32 ist es im Programm einfach, zwischen 16 und 32 Bit
zu unterscheiden, was ja z.B. bei Messages und DLL-Aufrufen notwendig sein kann:
IF %Win32
<Code für 32 Bit>
ELSE
<Code für 16 Bit>
ENDIF
%wmPaint
Seite 183
RGH-PROFAN²
Die Systemvariable wird auf 1 gesetzt, wenn das Eregnis wm_Paint ausgelöst wurde. Die
Meldung wm_Paint sendet Windows immer dann an ein Programm, wenn sein Fenster aus
welchen Gründen auchg immer ganz oder teilweise neu gezeichnet werden muß. Das
geschieht also z. B. jedesmal dann, wenn ein anderes Fenster das Fenster verdeckt oder
wenn das Fenster vergrößert wurde. Diese Meldung ist ein Ereignis, daß ein WAITINPUT
beendet.
wm_Paint wird nur ausgelöst, wenn das automatische Neuzeichnen mit SetAutoPaint
ausgeschaltet wurde. Erst beim Auslesen wird %wmPaint wieder auf 0 gesetzt. Da es
möglich ist, daß %wmPaint gesetzt wird, wenn auch andere Ereignisse auftreten, sollte es
ggf. in einer eigenen IF-Struktur abgefragt werden. Beispiel:
Seite 184
RGH-PROFAN²
CLS
SetAutoPaint 0
< ... Hier wird z.B. das Menü erzeugt, etc. ...>
WhileNot %Ende
WaitInput
If %wmPaint
<.. Fenster neu zeichnen ..>
EndIf
If ...
<... übrige Abfragen ..>
Endif
EndWhile
%wmTimer
wm_Timer wird ausgelöst, sobald der Timer mit SetTimer eingestellt wurde und das
Programm ein Hauptfenster hat. Das Ereignis beendet ein WAITINPUT. %wmTimer bleibt
solange auf 1, bis die Systemvariable ausgelesen wird. Dadurch wird sie auf 0 zurückgesetzt.
%WinTop
Die y-Koordinate des oberen Fensterrandes
%WinBottom
Die y-Koordinate des unteren Fensterrandes
%WinLeft
Die x-Koordinate des linken Fensterrandes
%WinRight
Die x Koordinate des rechten Fensterrandes
&BmpCol
Farbanzahl des zuletzt mit LOADBMP oder LOADSIZEDBMP geladenen Bildes.
&dbRecCount
Anzahl der Datensätze der aktiven Datenbanktabelle
&dbRecNo
Nummer des aktuellen Datensatzes.
Seite 185
RGH-PROFAN²
&GetTickCount
Die Systemvariable gibt die Anzahl von Millisekunden an, die vergangen sind, seit Windows
gestartet wurde.
Hinweis: Der interne Timer ist nach etwa 49 Tagen wieder bei Null angekommen, wenn
Windows nicht vorher beendet wird.
Die Systemvariable ermöglicht einfachere Zeitmessungen, als dies mit der @Time$-Funkton
möglich ist.
&Input
Der zuletzt mit Input eingegebene LongInt-Wert.
&SQLCount
Anzahl der vom letzen SQL-Befehl bearbeiteten Datensätze. Hat &SQLCount den Wert -1,
so ist ein Fehler aufgetreten.
Seite 186
RGH-PROFAN²
2. Funktionen
Eine Funktion gibt einen Wert zurück, der in der Regel von den Parametern der Funktion
abhängig ist. Überall da, wo in PROFAN² Variablen oder konstante Werte (Literale)
eingesetzt werden können, dürfen auch Funktionen stehen. Der Rückgabewert der Funktion
sollte der gleiche Typ sein, wie der erwartete Wert.
Alle Funktionsnamen in PROFAN² beginnen normalerweise mit einem @. Während viele
Anwender mit mir der Meinung sind, daß das @ den Quellcode übersichtlicher macht, indem
die Funktionen sofort erkennbar sind, gibt es auch einige, denen die Eingabe des @ (über
<AltGr><Q>) zu umständlich ist.
Ab dieser PROFAN²-Version (4.0) ist es möglich das @ überall wegzulassen. Im
Interpretermodus kann dies zu Geschwindigkeitseinbußen führen. Die Performance der
compilierten Programme ist davon unbeeinflußt.
Funktionen, deren Funktionsnamen mit dem $ endet, geben in vielen Fällen einen String
zurück, die übrigen Funktionen einen numerischen Wert. In einigen Fällen enden auch
Vergeleichsfunktionen, die entweder 1 oder 0 zurückgeben mit einem $, um deutlich zu
machen, das hiermit Strings verglichen werden.
Wenn der Rückgabewert einer Funktion uninteressant ist, kann die Zuweisung auch
weggelassen werden. Bis auf die immer noch notwendigen Klammern, wird die Funktion
dann wie ein Befehl verwandt.
Beispiel:
@LISTBOX$("Das ist die Liste",0)
In diesem Fall wird die Listbox nur zum Anschauen angezeigt oder aber das Ergebnis der
Auswahl über die Systemvariable $GETTEXT gelesen.
Seite 187
RGH-PROFAN²
@!(N)
N : Integer (0 ... 8)
Ergebnis: Float
Der N-te übergebene Parameter in einer selbstdefinierten Funktion (oder Prozedur) als Float.
@$(N)
N : Integer (0 ... 8)
Ergebnis: String
Der N-te übergebene Parameter in einer selbstdefinierten Funktion (oder Prozedur) als
String.
@%(N)
N : Integer (0 ... 8)
Ergebnis: Integer
Der N-te übergebene Parameter in einer selbstdefinierten Funktion (oder Prozedur) als
Integer.
@&(N)
N : Integer (0 ... 8)
Ergebnis: LongInt
Der N-te übergebene Parameter in einer selbstdefinierten Funktion (oder Prozedur) als
LongInt.
Der 0. Parameter ist nach Aufruf einer Prozedur oder einem Unterprogramm mit RETURN
<Wert> zurückgegebene Wert.
@Abs(N)
N : Wert
Ergebnis: Wert
Absolutwert der Zahl N.
Seite 188
RGH-PROFAN²
@Add$(S1,S2)
S1 : String
S2 : String
Ergebnis: String
Verknüpfung der Strings S1 und S2. S2 wird an S1 angehängt.
@Add(N1,N2)
N1 : Wert - Summand
N2 : Wert - Summand
Ergebnis: Wert
Die Summe von N1 und N2.
Siehe auch: @Add$
@AddChoice(N,S)
N: Integer - Handle der Auswahlbox
S: String - hinzuzufügender String
Ergebnis: Integer - Erfolg
Der Auswahlbox mit dem Handle N wird der String S hinzugefügt. Er wird einsortiert.
@AddString(N,S)
N: Integer - Handle der Listbox
S: String - hinzuzufügender String
Ergebnis: Integer - Erfolg
Der Listbox mit dem Handle N wird der String S hinzugefügt. Bei einer unsortierten Listbox
wird er hinten angehängt, während er bei einer sortierten Listbox einsortiert wird.
@And(N1,N2)
N1 : Wert
N2 : Wert
Ergebnis: Wert
Die Werte von N1 und N2 werden mit der AND-Funktion verknüpft. Das Ergebnis ist 0 wenn
ein oder beide Werte 0 sind.
Vergleiche: @OR, @NOT
Seite 189
RGH-PROFAN²
@AnsiToOem$(S)
S : String
Ergebnis: String
Der String S wird von ANSI-Code in den ASCII-Code (OEM) umgewandelt. Diese
Umwandlungen betreffen insbesondere die deutschen Sonderzeichen. Der ASCII-Code wird
unter DOS verwandt, der ANSI-Code unter Windows.
@ArcTan(N)
N : Wert (Winkel in Bogenmaß)
Ergebnis : Float
Der Arcustangens des Winkels N.
Seite 190
RGH-PROFAN²
@Bin$(N) - @Oct$(N) - @Hex$(N)
N : Integer oder LongInt - umzuwandelnder Wert
Mir diesen Funktionen lassen sich Integerwerte (Integer und LongInt) in die Darstellung
anderer Zahlensysteme übertragen. Hierbei steht BIN für die binäre Darstellung, OCT für die
octale Darstellung und HEX für die Hexadezimale Darstellung. @Bin$(10) ergibt also "1010",
@Oct$(10) ergibt "12" und @Hex$(10) ergibt "A".
@BlockRead(#N,B,N1,N2)
#N : Dateikennung
B : Bereichsvariable
N1 : LongInt - Adresse in der Bereichsvariablen
N2 : LongInt - Anzahl Bytes
Ergebnis: LongInt - tatsächlich gelesene Bytes
Aus der mit OPENRW geöffneten Datei mit der Kennung #K werden maximal N2 Bytes
(ausgehend von der aktuellen Position des Dateizeigers) gelesen und in der
Bereichsvariablen B ab Adresse N1 abgelegt. Wird das Dateiende erreicht, bevor N2 Bytes
gelesen wurden, wird als Ergebnis nur die Anzahl der tatsächlich gelesenen Bytes
zurückgeliefert. Es können in der 16-Bit-Version nur max. 65520 Bytes gelesen werden.
Beispiel:
Declare B#,Anzahl%
Dim B#,500
Assign #1,"TEST.DAT"
OpenRW #1
Let Anzahl% = @BlockRead(#1,B#,0,500)
CloseRW #1
Print Anzahl%;" Bytes gelesen!"
@Byte(V,A)
V: Bereichsvariable
A: LongInt - Adresse
Ergebnis: Integer - Wert
Diese Funktion ermittelt der Wert des Bytes an der Adresse (Offset) A in der
Bereichsvariablen V. Ist A außerhalb des mit DIM eingestellten Bereiches von V, erfolgt eine
Fehlermeldung.
Seite 191
RGH-PROFAN²
@ChooseDir$(S)
S : String - Titel der Dialogbox
Ergebnis : String - gewählter Pfad
Die Funktion ruft den Verzeichniswahl-Dialog auf. Er ähnelt dem SAVE-Dialog mit dem
Unterschied, daß kein Dateiname eingegeben werden kann. Der Rückgabewert ist der
gewählte Pfad:
Let Pfad$ = @ChooseDir$("Verzeichnis wählen:")
ChDir Pfad$
Bitte beachten: Der Dialog selbst wechselt nicht in den Pfad, sondern er gibt nur einen
vorhandenen und gewählten Pfad zurück. Wird er mit "Abbruch" beendet, ist der
Rückgabestring leer!
@Chr$(N)
N : Wert (0 .. 255)
Ergebnis: String (1 Zeichen)
Das Zeichen mit dem ANSI-Code N.
@CloseCom(N)
N:: Integer - Handle der Schnittstelle
Ergebnis: Integer - Fehlercode
Die Schnittstelle wird geschlossen. Im Fehlerfalle ist das Ergebnis negativ, ansonsten wird 0
zurückgegeben.
@ComError(N)
N: Integer - Handle der Schnittstelle
Ergebnis: Integer - Fehlerstatus
Die Funktion ermittelt den letzten Fehlerwert und den aktuellen Status für das angegebene
Gerät. Tritt ein Schnittstellenfehler auf, sperrt Windows die Schnittstelle, bis der Fehler durch
Aufruf der Funktion @COMERROR behoben wird. Daher sollte die Funktion nach jedem
@READCOM bzw. @WRITECOM aufgerufen werden!
Seite 192
RGH-PROFAN²
Der Rückgabewert kann eine Kombination aus folgenden Werten sein:
$0001 - Überlauf der Empfangswarteschlange. Entweder reicht der Platz in der
Empfangswarteschlange nicht aus, oder die Übertragung wurde nach Erhalt des
End-of-file-Zeichens fortgesetzt.
$0002 - Ein Zeichen wird von der Hardware nicht rechtzeitig gelesen. Das Zeichen ist
verloren.
$0004 - Die Hardware stellte einen Parity-Fehler fest.
$0008 - Die Hardware stellt einen Framing-Fehler fest.
$0010 - Die Hardware stellte eine Abbruchbedingung fest.
$0020 - Clear-to-send-Unterbrechung (time out).
$0040 - Data-set-ready-Unterbrechung.
$0080 - Receive-line-signal-detect-Unterbrechung.
$0100 - Die Sendewarteschlange war voll.
$0200 - Bei der Kommunikation mit der parallelen Schnittstelle trat ein Timeout auf.
$0400 - Ein I/O-Fehler trat während des Versuchs der Kommunikation mit einer parallelen
Schnittstelle auf.
$0800 - Die parallele Schnittstelle war nicht gewählt.
$1000 - Gerät an der parallelen Schnittstelle meldet Papierende.
$8000 - Der gewünschte Modus wird nicht unterstützt, oder der Parameter H% ist fehlerhaft.
@Control(S1,S2,N1,X,Y,DX,DY,N2,N3,N4)
S1 : Klassenname (muß Windows bekannt sein)
S2 : ggf. Text/Überschrift
N1: Stil
X,Y : linke, obere Ecke des Controls auf dem Fenster
DX,DY : Größe des Controls
N2 : Übergeordnetes Fenster
N3 : Bei Fenstern mit Menüs das Menühandle
Bei Dialogelementen die Nummer des Dialogelementes
(Bei mehreren mit @Control erzeugten Dialogelementen
eines Fensters sollte jedes einen anderen Wert erhalten.
N4 : Instanz des Programmes (i.d.R. %HINSTANCE)
Ergebnis : Integer - Handle des Dialogelementes
Nähere Hinweise zu den Parametern finden Sie in der Windows-Literatur zur Erläuterung der
API-Funktion "CreateWindow". Die Reihenfolge und Bedeutung der Parameter ist dort die
Gleiche.
Mit dieser Funktion können beliebige registrierte (Windows bekanntrgemachte)
Dialogelemente, deren Klassenname und mögliche Stil-Werte bekannt sind, erzeugt werden.
Neben neuen Controls, die etwa in DLLs geliefert werden, können auch die Standardcontrols
verwandt werden und mit Eigenschaften versehen werden, die PROFAN² sonst nicht bietet.
Zentrierter bzw. nach rechts ausgerichteter Text sind nun kein Problem mehr (Klasse
"STATIC", Stil $50000001 bzw. $50000002).
Hier die Klassennamen für die wichtigsten Standardcontrols und die Werte für die
Wichtigsten Stile:
Klassennamen: BUTTON, COMBOBOX, EDIT (ein- oder mehrzeilig, je nach Stil), LISTBOX,
MDICLIENT, SCROLLBAR, STATIC (Text oder Icon, je nach Stil)
Allgemeine Fensterstile:
ws_Overlapped
ws_Popup
ws_Child
ws_Minimize
ws_Visible
=
=
=
=
=
$00000000
$80000000
$40000000
$20000000
$10000000
Seite 193
RGH-PROFAN²
ws_Disabled
ws_ClipSiblings
ws_ClipChildren
ws_Maximize
ws_Caption
ws_Border
ws_DlgFrame
ws_VScroll
ws_HScroll
ws_SysMenu
ws_ThickFrame
ws_Group
ws_TabStop
=
=
=
=
=
=
=
=
=
=
=
=
=
$08000000
$04000000
$02000000
$01000000
$00C00000
$00800000
$00400000
$00200000
$00100000
$00080000
$00040000
$00020000
$00010000
ws_MinimizeBox
ws_MaximizeBox
= $00020000
= $00010000
{ ws_Border + ws_DlgFrame }
Seite 194
RGH-PROFAN²
Edit-Control-Stile
es_Left
es_Center
es_Right
es_MultiLine
es_UpperCase
es_LowerCase
es_Password
es_AutoVScroll
es_AutoHScroll
es_NoHideSel
es_OEMConvert
=
=
=
=
=
=
=
=
=
=
=
$0000
$0001
$0002
$0004
$0008
$0010
$0020
$0040
$0080
$0100
$0400
Button-Stile:
bs_PushButton
bs_DefPushButton
bs_CheckBox
bs_AutoCheckBox
bs_RadioButton
bs_3State
bs_Auto3State
bs_GroupBox
bs_UserButton
bs_AutoRadioButton
bs_PushBox
bs_OwnerDraw
bs_LeftText
=
=
=
=
=
=
=
=
=
=
=
=
=
$00
$01
$02
$03
$04
$05
$06
$07
$08
$09
$0A
$0B
$20
Listbox-Stile
lbs_Notify
lbs_Sort
lbs_NoRedraw
lbs_MultipleSel
lbs_OwnerDrawFixed
lbs_OwnerDrawVariable
lbs_HasStrings
lbs_UseTabStops
lbs_NoIntegralHeight
lbs_MultiColumn
lbs_WantKeyboardInput
lbs_ExtendedSel
lbs_Standard
=
=
=
=
=
=
=
=
=
=
=
=
=
$0001
$0002
$0004
$0008
$0010
$0020
$0040
$0080
$0100
$0200
$0400
$0800
lbs_Notify + lbs_Sort + ws_VScroll + ws_Border
Combo-Box-Stile (Auswahlbox)
cbs_Simple
cbs_DropDown
cbs_DropDownList
cbs_OwnerDrawFixed
cbs_OwnerDrawVariable
cbs_AutoHScroll
cbs_OEMConvert
cbs_Sort
cbs_HasStrings
cbs_NoIntegralHeight
=
=
=
=
=
=
=
=
=
=
$0001
$0002
$0003
$0010
$0020
$0040
$0080
$0100
$0200
$0400
Scroll-Bar-Stile:
sbs_Horz
sbs_Vert
sbs_TopAlign
sbs_LeftAlign
sbs_BottomAlign
sbs_RightAlign
sbs_SizeBoxTopLeftAlign
sbs_SizeBoxBottomRightAlign
sbs_SizeBox
=
=
=
=
=
=
=
=
=
$0000
$0001
$0002
$0002
$0004
$0004
$0002
$0004
$0008
(Größenveränderungsbox)
Seite 195
RGH-PROFAN²
Static Control Constants (Stile für statische Controls - Text und Icon)
ss_Left
ss_Center
ss_Right
ss_Icon
ss_BlackRect
ss_GrayRect
ss_WhiteRect
ss_BlackFrame
ss_GrayFrame
ss_WhiteFrame
ss_UserItem
ss_Simple
ss_LeftNoWordWrap
ss_NoPrefix
=
=
=
=
=
=
=
=
=
=
=
=
=
=
$00
$01
$02
$03
$04
$05
$06
$07
$08
$09
$0A
$0B
$0C
$80
Dialog-Stile
ds_AbsAlign
ds_SysModal
ds_LocalEdit
ds_SetFont
ds_ModalFrame
ds_NoIdleMsg
=
=
=
=
=
=
$01
$02
$20
$40
$80
$100
{
{
{
{
Edit items get Local storage }
User specified font for Dlg controls }
Can be combined with ws_Caption }
wm_EnterIdle message will not be sent }
Mehrere Stilkonstanten können durch Addition bzw. mittels OR kombiniert werden. Näheres,
insbesondere die Erklärungen zu den Klassen und Stilen, entnehmen Sie bitte der
einschlägigen Fachliteratur!
@Cot(N)
N : Wert (Winkel in Bogenmaß)
Ergebnis : Float
Der Cotangens des Winkels N.
@Cos(N)
N : Wert (Winkel in Bogenmaß)
Ergebnis : Float
Der Cosinus des Winkels N.
@CreateButton(N,S,X1,Y1,X2,Y2)
N : Integer - Handle des übergeordneten Fensters
S : String - Text auf dem Button
X1,Y1 : Integer - Linke obere Ecke des Buttons
X2,Y2 : Integer - Größe des Buttons
Ergebnis : Integer - Handle des Buttons
Es wird ein Button (Schaltfläche) erzeugt. Parameter N ist das Handle der Dialogbox oder
des Fensters auf dem sich der Button befindet. Die Koordinatenangaben sind relativ zu
dieser Dialogbox oder diesem Fenster.
Sie auch: @CreateDefButton
Seite 196
RGH-PROFAN²
Seite 197
RGH-PROFAN²
@CreateCheckBox(N,S,X1,Y1,X2,Y2)
N : Integer - Handle des übergeordneten Fensters
S : String - Text rechts neben der Checkbox
X1,Y1 : Integer - Linke obere Ecke der Checkbox
X2,Y2 : Integer - Größe der Checkbox (inclusive Text)
Ergebnis : Integer - Handle der CheckBox
Es wird eine CheckBox (Kästchen zum ankreuzen) erzeugt. Parameter N ist das Handle der
Dialogbox oder des Fensters auf dem sich die Checkbox befindet. Die Koordinatenangaben
sind relativ zu dieser Dialogbox oder diesem Fenster.
Siehe auch: @CreateRadioButton
@CreateChoiceBox(N,S,X1,X2,Y1,Y2)
N : Integer - Handle des übergeordneten Fensters
S : String - muß ein Leerstring sein
X1,Y1 : Integer - Linke obere Ecke der AuswahlBox
X2,Y2 : Integer - Größe der AuswahlBox
Ergebnis : Integer - Handle des erzeugten Objektes
Es wird eine Auswahlbox erzeugt und ihr Handle zurückgegeben. Der zweite Parameter
sollte ein Leerstring sein. Auch eine Zuweisung mit SETTEXT (oder äquivalenten Befehlen)
sollte unterlassen werden, da dies zu unvorhersehbaren Reaktionen führen kann.
Eine Auswahlbox ist eine Sonderform der sogenannten "Combobox": Durch Anklicken des
Pfeiles nach unten kann aus einer Liste von Auswahlmöglichkeiten eine Zeile ausgewählt
werden. Eine Eingabe von Zeilen ist nicht möglich. Die ausgewählte Zeile kann mit der
Funktion @GETTEXT$ ermittelt werden. Eine Auswahlbox ist immer alphabetisch sortiert.
@CreateDefButton(N,S,X1,Y1,X2,Y2)
N : Integer - Handle des übergeordneten Fensters
S : String - Text auf dem Button
X1,Y1 : Integer - Linke obere Ecke des Buttons
X2,Y2 : Integer - Größe des Buttons
Ergebnis : Integer - Handle des Buttons
Es wird ein Button (Schaltfläche) erzeugt. Parameter N ist das Handle der Dialogbox oder
des Fensters auf dem sich der Button befindet. Die Koordinatenangaben sind relativ zu
dieser Dialogbox oder diesem Fenster. Der Button ist defaultmäßig aktiviert.
Siehe auch: @CreateButton
Seite 198
RGH-PROFAN²
@CreateDialog(N,S,X1,Y1,X2,Y2)
N : Integer - Handle des übergeordneten Fensters
S : String - Dialog-Überschrift
X1,Y1 : Integer - Linke obere Ecke der Dialogbox
X2,Y2 : Integer - Größe des Dialogbox
Ergebnis : Integer - Handle des erzeugten Dialoges
Es wird eine Dialogbox mit der Überschrift S erzeugt. Eine Dialogbox in PROFAN kann
weder vergrößert oder verkleinert werden. Wenn CTRL3D.DLL im System ist, werden auch
die selbsterzeugten Dialoge im 3D-Look angezeigt. In diese Dialogbox können alle in
PROFAN möglichen Fensterobjekte plaziert werden. Wird die Dialogbox mit
@DESTROYWINDOW zerstört, verschwinden auch alle von ihr abhängigen Fensterobjekte.
@CreateEdit(N,S,X1,Y1,X2,Y2)
N : Integer - Handle des übergeordneten Fensters
S : String - Vorgabetext
X1,Y1 : Integer - Linke obere Ecke des Eingabefeldes
X2,Y2 : Integer - Größe des Eingabefeldes
Ergebnis : Integer - Handle des erzeugten Objektes
Es wird ein Eingabefeld zur Eingabe eines Strings erzeugt. S ist ein Vorgabewert für diesen
String. Soll das Fenster anfänglich leer sein, ist ein Leerstring anzugeben. Parameter N ist
das Handle der Dialogbox oder des Fensters auf dem sich das Eingabefeld befindet. Die
Koordinatenangaben sind relativ zu dieser Dialogbox oder diesem Fenster. Wird Y2 als
negativer Wert angegeben, so wird zwar trotzdem der absolute Wert als Größe genommen,
aber gleichzeitig die Paßwortfunktion aktiviert: Alle eingegebenen Zeichen werden durch
Sterne dargestellt.
@CreateExtDialog
I
H
S
: Integer - Instanz-Handle der Datei, in der der Dialog ist
: Integer - Handle des übergeordneten Fensters
: String - Name des Dialogs
Ergebnis : Integer - Handle des erzeugten Dialoges
Es wird ein Dialog aus einer Resource angezeigt. Dialog-Resourcen können wahlweise durch
einen Namen oder einen Integer gekennzeichnet sein. Daher darf der dritte Parameter ggf.
auch ein Integer sein, etwa:
Let Dlg% = @CreateExtDialog(I%,%HWnd,1001)
Das Instanz-Handle wird bei DLLs mittels @UseDLL ermittelt und bei EXE-Dateien mittels
@WinExec. Das Handle des ausführenden Programmes ist in der Systemvariablen
%HInstance.
Es ist also möglich, alle in einem Programm verwandten Dialoge mittels eines Tools wie des
Resource-Workshops von Borland in eine DLL zu packen. Ebenso ist es z.B. möglich, die
PROFRUN.EXE vor dem Linken entsprechend zu erweitern, bzw. die vorhandenen Dialoge
zu benutzen.
Mit @GetHandle ermitteln Sie die Handle der einzelnen Dialogelemente, wie Listboxen,
Eingabefelder, etc.
Seite 199
RGH-PROFAN²
Hier ein einfaches Beispiel, daß den Datei-Öffnen Dialog aus PROFAN.EXE bzw.
PROFRUN.EXE (Instanz-Handle = %HInstance) aufruft und angezeigt und ihn beim Drücken
des OK-Buttons oder Abbruch-Buttons wieder verläßt. Mit dem Resource-Workshop von
Borland läßt sich leicht ermitteln, daß der Dialog "FILEOPEN" heißt und der OK-Button den
Wert 1 hat und der Abbruch-Button den Wert 2:
Declare Ok%, Dlg%, Abbruch%, Ende%
CLS
Let Dlg% = @CreateExtDialog(%HInstance,%HWnd,"FILEOPEN")
Let Ok% = @GetHandle(Dlg%,1)
Let Abbruch% = @GetHandle(Dlg%,2)
Let Ende% = 0
WHILENOT Ende%
WaitInput
IF @GetFocus(Ok%)
Print "OK"
Let Ende% = 1
ELSEIF @GetFokus(Abbruch%)
Print "ABBRUCH"
Let Ende% = 1
ENDIF
ENDWHILE
END
@CreateGroupBox(N,S,X1,Y1,X2,Y2)
N : Integer - Handle des übergeordneten Fensters
S : String - Text, der links oben im Tahmen steht
X1,Y1 : Integer - Linke obere Ecke des Gruppen-Rahmens
X2,Y2 : Integer - Größe des Rahmens
Ergebnis : Integer - Handle des erzeugten Objektes
Es wird eine Gruppen-Rahmen erzeugt. Parameter N ist das Handle der Dialogbox oder des
Fensters auf dem sich der Rahmen befindet. Die Koordinatenangaben sind relativ zu dieser
Dialogbox oder diesem Fenster. Der Gruppen-Rahmen wird zur optischen Gruppierung
innerhalb von Dialogboxen eingesetzt, aber auch zum gruppieren der Radiobuttons.
@CreateHScroll(N,S,X1,X2,Y1,Y2)
N : Integer - Handle des übergeordneten Fensters
S : String - muß ein Leerstring sein
X1,Y1 : Integer - Linke obere Ecke des Scrollbalkens
X2,Y2 : Integer - Größe des Scrollbalkens
Ergebnis : Integer - Handle des erzeugten Objektes
Es wird ein horizontaler Scrollbalken erzeugt und sein Handle zurückgegeben. Der zweite
Parameter sollte ein Leerstring sein. Standardmäßig ist der Wertebereich von 0 - 100
eigestellt; er kann aber mit SetScrollRange verändert werden. Mit @GetScrollPos kann der
eingestellte Wert ausgelesen werden, mit SetScrollPos wird ein Wert eingestellt.
@CreateIcon(N,S,X1,Y1)
N : Integer - Handle des übergeordneten Fensters
S : String - Name des Icons
X1,Y1 : Integer - Linke obere Ecke des Icons
Seite 200
RGH-PROFAN²
Ergebnis : Integer - Handle des erzeugten Objektes
Es wird ein Iconfeld zur Anzeige des Icons mit dem Namen S erzeugt. Parameter N ist das
Handle der Dialogbox oder des Fensters auf dem sich das Iconfeld befindet. Die
Koordinatenangaben sind relativ zu dieser Dialogbox oder diesem Fenster.
@CreateListBox(N,S,X1,X2,Y1,Y2)
N : Integer - Handle des übergeordneten Fensters
S : String - muß ein Leerstring sein
X1,Y1 : Integer - Linke obere Ecke der ListBox
X2,Y2 : Integer - Größe der ListBox
Ergebnis : Integer - Handle des erzeugten Objektes
Es wird eine Listbox erzeugt und ihr Handle zurückgegeben. Der zweite Parameter sollte ein
Leerstring sein. Auch eine Zuweisung mit SETTEXT (oder äquivalenten Befehlen) sollte
unterlassen werden, da dies zu unvorhersehbaren Reaktionen führen kann.
Siehe auch: @CreateSortedListbox
@CreateMultiEdit(N,S,X1,X2,Y1,Y2)
N : Integer - Handle des übergeordneten Fensters
S : String - Text
X1,Y1 : Integer - Linke obere Ecke der EditBox
X2,Y2 : Integer - Größe der EditBox
Ergebnis : Integer - Handle des erzeugten Objektes
Es wird ein mehrzeiliges Editierfeld erzeugt und sein Handle zurückgegeben. Der zweite
Parameter kann ein anfänglicher Text sein. Solange der Text nicht über 255 Zeichen lang ist,
kann er mit SETTEXT zugewiesen und mit der Funktion @GETTEXT$ ermittelt werden. Für
längere Texte ist die z.B. Funktion @MOVELISTTOEDIT zu verwenden oder mit der
Funktion @SENDMESSAGE der Inhalt einer Bereichsvariablen an das Editierfeld zu
senden. Beispiel:
DECLARE Edit%,Bereich#
LET Edit% = @CreateMultiEdit(%HWnd,"",10,10,200,200)
DIM Bereich#,@Add(@FileSize("C:\PROFAN40\LIESMICH.TXT"),2)
@ReadText Bereich#,"C:\PROFAN40\LIESMICH.TXT"
@SendMessage(Edit%,$000C,0,Bereich#)
WaitInput
End
Wird Y2 als negativer Wert angegeben, so wird zwar trotzdem der absolute Wert als Größe
genommen, aber gleichzeitig die automatische Wortumbruch-Funktion aktiviert: Der
horizontale Scrollbalken wird nicht angezeigt und ein Wort, das nicht mehr in eine Zeile paßt
wird automatisch in die nächste Zeile gebracht.
Seite 201
RGH-PROFAN²
@CreateRadioButton(N,S,X1,Y1,X2,Y2)
N : Integer - Handle des übergeordneten Fensters
S : String - Text rechts neben dem RadioButton
X1,Y1 : Integer - Linke obere Ecke des RadioButton
X2,Y2 : Integer - Größe des RadioButton (inclusive Text)
Ergebnis : Integer - Handle des erzeugten Objektes
Es wird eine RadioButton erzeugt. Parameter N ist das Handle der Dialogbox oder des
Fensters auf dem sich der RadioButton befindet. Die Koordinatenangaben sind relativ zu
dieser Dialogbox oder diesem Fenster. Mehrere RadioButtons werden in einer Gruppe
zusammengefaßt. Immer nur ein RadioButton einer Gruppe kann aktiviert sein. Eine neue
Gruppe wird durch die Funktion @CREATEGROUPBOX markiert. Diese Gruppe ist "gültig"
bis zum nächsten @CREATEGROUPBOX.
Siehe auch: @CreateCheckBox
@CreateSortedListBox(N,S,X1,X2,Y1,Y2)
N : Integer - Handle des übergeordneten Fensters
S : String - muß ein Leerstring sein
X1,Y1 : Integer - Linke obere Ecke der ListBox
X2,Y2 : Integer - Größe der ListBox
Ergebnis : Integer - Handle des erzeugten Objektes
Es wird eine sortierte Listbox erzeugt.
Siehe auch: @CreateListBox
@CreateText(N,S,X1,Y1,X2,Y2)
N : Integer - Handle des übergeordneten Fensters
S : String - Text
X1,Y1 : Integer - Linke obere Ecke des Textes
X2,Y2 : Integer - Größe des Textfeldes
Ergebnis : Integer - Handle des erzeugten Objektes
Es wird ein Textfeld zur Anzeige des Textes S erzeugt. Parameter N ist das Handle der
Dialogbox oder des Fensters auf dem sich das Textfeld befindet. Die Koordinatenangaben
sind relativ zu dieser Dialogbox oder diesem Fenster. Da in Dialogboxen bzw. Dialogfenstern
die Befehle PRINT oder DRAWTEXT nicht anwendbar sind, ist das Textfeld dort die einzige
Möglichkeit, Text anzuzeigen.
@CreateVScroll(N,S,X1,X2,Y1,Y2)
N : Integer - Handle des übergeordneten Fensters
S : String - muß ein Leerstring sein
X1,Y1 : Integer - Linke obere Ecke des Scrollbalkens
X2,Y2 : Integer - Größe des Scrollbalkens
Ergebnis : Integer - Handle des erzeugten Objektes
Seite 202
RGH-PROFAN²
Es wird ein vertikaler Scrollbalken erzeugt und sein Handle zurückgegeben. Der zweite
Parameter sollte ein Leerstring sein. Standardmäßig ist der Wertebereich von 0 - 100
eigestellt; er kann aber mit SetScrollRange verändert werden. Mit @GetScrollPos kann der
eingestellte Wert ausgelesen werden, mit SetScrollPos wird ein Wert eingestellt.
@CreateWindow(N,S,X1,Y1,X2,Y2)
N : Integer - Handle des übergeordneten Fensters
S : String - Fenster-Überschrift
X1,Y1 : Integer - Linke obere Ecke des Dialogfensters
X2,Y2 : Integer - Größe des Dialogfensters
Ergebnis : Integer - Handle des erzeugten Fensters
Es wird ein Dialogfenster mit der Überschrift S erzeugt. Der Fensterstil kann vorher mit
WINDOWSTYLE eingestellt werden. Da Das Dialogfenster alle in PROFAN² möglichen
Fensterstile haben kann, kann es z.B. auch bei Bedarf verkleinert oder als Icon dargestellt
werden. Ansonsten verhält sich ein Dialogfenster exakt so, wie die Dialogbox. Lediglich die
3D-Elemente werden nicht verwandt.
@CToD$(S)
S : String - Datum im landesspezifischen Format
Ergebnis : String - Datum im Datenbankformat
Diese Funktion wandelt ein Datum im landesspezifischen Format (z.B. "TT.MM.JJJJ") in das
Format der Datenbank um.
Seite 203
RGH-PROFAN²
@Date$(N)
N : Integer - Ausgabeform
Ergebnis: String - Datum
Die Funktion ermittelt das aktuelle Datum in verschieden Formaten:
0 : Kurzform im landesspezifischen Format (z.B. "09.04.1993")
1 : Langform (z.B. "9. April 1993") *
2 : Langform mit Tag (z.B. "Freitag, der 9. April 1993") *
3 : Datenbankformat JJJJMMTT (z.B. "19930409")
4 : Datumsformatkennung aus der WIN.INI
Ausgabeform 4 gibt das in der WIN.INI eingestellte Datumsformat zurück, wobei das erste
Zeichen das Trennzeichen ist und die drei folgenden für die Reihenfolge von Jahr (y), Monat
(M) und Tag (d) stehen, z.B. ".dMy".
* Die Formen 1 und 2 gelten nur für die deutsche Version von PROFAN² und geben immer
die deutsche Form zurück.
@dbAppendBlank()
Ergebnis : LongInt - Nummer des aktuellen Datensatzes
Ein leerer Datensatz wird an die Datenbank angehängt und kann nun bearbeitet werden. Das
Ergebnis ist die Nummer des neuen Datensatzes.
@dbClose(#N)
N : Integer - Tabellenkennzeichen (1 .. 8)
Ergebnis : LongInt - Anzahl der Datensätze
Die Funktion schließt die Datenbanktaballe mit der Kennung N. Jede geöffnete
Datenbanktabelle muß im Programm wieder geschlossen werden; anderenfalls können
Daten verloren gehen.
@dbDelete()
Ergebnis : LongInt - Nummer des Datensatzes.
Der aktuelle Datensatz wird als gelöscht gekennzeichnet.
Seite 204
RGH-PROFAN²
@dbFind(S,N)
S : String - Suchbegriff
N : Integer - Genauigkeit
Ergebnis : Nummer des gefundenen Datensatzes
Es wird der Datensatz gesucht, der S im Indexfeld enthält. (Bei mehreren Indices zählt der
erste Index). N bestimmt, wie exakt gesucht wird:
0 - Es wird der erste Datensatz gefunden, der mit dem Suchbegriff S beginnt.
1 - Es wird der erste Datensatz gefunden, der mit dem Suchbegriff S identisch ist.
Ergebnis: Datensatznummer des gefundenen Satzes. Es wird auf diesen Datensatz
positioniert. Wurde keiner gefunden, ist das Ergebnis 0.
(XBase: FIND S)
Siehe auch: @dbSeek
@dbGet$(S)
S : String - Feldname
Ergebnis : String - Feldinhalt
Das Feld S des aktuellen Datensatzes wird gelesen. Das Ergebnis ist ein String. Beispiel:
Let Name$ = @DBGet$("NAME")
Bei numerischen Feldern kann der String mit @Str$ in eine entsprechende Zahl
umgewandelt werden. Für die Umwandlung von Datumsfeldern gibt es die Funktion
@DTOC$.
Siehe auch: @dbGetField$
@dbGetField$(N)
N : Integer - Nummer des Feldes
Ergebnis : String - Feldinhalt
Das Feld mit der Feldnummer N wird gelesen. Hier wird anstelle des Feldnamens die
Feldnummer angegeben.
Siehe auch :dbGet$
Seite 205
RGH-PROFAN²
@dbGetMemo(S)
S: String - Feldname
Ergebnis: Integer - Abzahl der Zeichen im Memo-Text
Wenn S ein Memo-Feld bezeichnet wird der dazugehörige Text aus der Memo-Datei in die
Listboxliste übertragen. Zuvor wird sie geleert. Ist S kein Memo-Feld ist der Rückgabewert
0, ist S hingegen ein Memo-Feld ohne Text, wird 0 zurückgeliefert.
Der Inhalt der Listboxliste kann z.B. mit @LISTBOX$ angezeigt oder mit @EDITBOX
bearbeitet werden. Mit @DBPUTMEMO wird der geänderte Inhalt wieder zurückgeschrieben.
Um in Erfahrung zu bringen, ob eine Tabelle überhaupt Memo-Felder hat, ist die
Systemvariable %DBMEMO zu verwenden.
Mit folgender Prozedur kann der dBase-Befehl MEMOEDIT nachgebildet werden, mit dem
ein Memo-Feld gelesen, geändert und zurückgeschrieben wird:
PROC MEMOEDIT
Parameters FeldName$
@DBGETMEMO(FeldName$)
IF @EDITBOX("Memo editieren",1)
@DBPUTMEMO(FeldName$)
ENDIF
ENDPROC
Aufgerufen wird die Prozedur mit dem Feldnamen des Memofeldes als Parameter.
@dbGo(N)
N : LongInt - Datensatznummer oder Datensatzbezeichner
Ergebnis : LongInt - Datensatznummer
Satz N wird zum aktuellen Datensatz und zum Bearbeiten aus der Tabelle in den Speicher
geladen. Diese Arbeitskopie des Datensatzes wird mit den folgenden Funktionen gelesen
und geändert. Anstelle der Satznummer N können auch folgende Datensatzbezeichner
stehen:
"|<" oder "TOP"
">|" oder "BOTTOM"
">" oder "NEXT"
"<" oder "PREV"
-
geht
geht
geht
geht
zum
zum
zum
zum
ersten Datensatz
letzten Datensatz
nächsten Datensatz
vorhergehenden Datensatz
Beispiel:
DBGO("NEXT")
Wenn ein Index (oder mehrere Indices) geöffnet sind, wird dieser berücksichtigt. Das
Ergebnis ist die Nummer des Datensatzes, zu dem positioniert wurde.
Seite 206
RGH-PROFAN²
@dbIndex(S)
S : String - Namen der Indexdatei(en)
Ergebnis : Integer - 1=OK, 0=Fehler
Der Index wird genutzt. S enthält den (oder die) Namen der Indexdatei. Es können durch
Kommata getrennt mehrere Indexdateien angegeben werden. Beispiel:
LET X% = @DBIndex("IXNAME,IXORT")
Das Ergebnis ist 1, wenn der Index gewählt werden konnte und 0, wenn ein Fehler auftrat,
weil mindestens eine der Index-Dateien fehlen.
(XBase: USE INDEX S)
@dbOpen(#N,S)
N : Integer - Tabellenkennzeichen (1 - 15)
S : String - Dateiname der Datenbanktabelle
Ergebnis : LongInt - Anzahl der Datensätze in der Tabelle
Die Datenbanktabelle S (Tabelle im DBF-Format) wird geöffnet. N kann Werte von 1 bis 15
annehmen. Es können bis zu 15 Tabellen gleichzeitig geöffnet sein. Das Ergebnis ist die
Anzahl der Datensätze in der Tabelle. Beispiel:
LET Anz& = @DBOpen(#1,"KUNDEN.DBF")
@dbPack()
Ergebnis : Anzahl der Datensätze
Alle als gelöscht markierten Datensätze werden endgültig aus der Datenbanktabelle entfernt.
Das Ergebnis ist die Anzahl der verbleibenden Datensätze.
Siehe auch: %dbDeleted
@dbPut(S1,S2)
S1 : String - Name des Feldes
S2 : String - Neuer Inhalt
Ergebnis : Integer (ohne Bedeutung: immer 1)
Der String S2 wird in Feld S1 des aktuellen Datensatzes geschrieben.
WICHTIG: Dieser Befehl betrifft nur die "Arbeitskopie" des Datensatzes im Speicher. Erst mit
@DBPUTREC wird er endgültig in die Datenbanktabelle geschrieben.
(XBase: REPLACE S1 WITH S2)
Siehe auch: @dbPutField
Seite 207
RGH-PROFAN²
@dbPutField(N,S)
N : Integer - Nummer des Feldes
S : String - Neuer Inhalt
Ergebnis : Integer (ohne Bedeutung: immer 1)
Der String S wird in Feld Nummer N des aktuellen Datensatzes geschrieben.
WICHTIG: Dieser Befehl betrifft nur die "Arbeitskopie" des Datensatzes im Speicher. Erst mit
@DBPUTREC wird er endgültig in die Datenbanktabelle geschrieben.
Siehe auch: @dbPut
@dbPutMemo(S)
S: String - Feldname
Ergebnis: Integer - Erfolg
Wenn S ein Memo-Feld bezeichnet, wird der Inhalt der Listboxliste in die dazugehörige
Memo-Datei geschrieben und der Inhalt des Memofeldes (der Veweis auf die Memo-Datei)
entsprechend aktualisiert. Trat ein Fehler auf oder bezeichnet S kein Memo-Feld, dann ist
der Rückgabewert der Funktion 0, anderenfalls ist er 1.
@dbPutRec(N)
N : LongInt - Datensatznummer
Ergebnis: LongInt - Nummer des geschriebenen Satzes
Der aktuelle Datensatz (die Arbeitskopie im Speicher) wird als Datensatz an Position N in die
Datenbanktabelle geschrieben. Hat N der Wert 0, wird der aktuell positionierte Datensatz mit
den neuen Werten überschrieben. Ergebnis: aktuelle Datensatznummer.
@dbSeek(S1,S2)
S1 : String - Name des Feldes, in dem gesucht wird
S2 : String - Suchbegriff
N : Integer - Suchgenauigkeit (0, 1 oder 2)
Ergebnis : Nummer des gefundenen Datensatzes
Suche ohne Index in einem beliebigen Feld des Datensatzes. Es wird der erste Datensatz
gefunden, der im gewünschten Feld den Suchbegriff enthält. Die Suche beginnt mit dem
aktuellen Datensatz.
Ergebnis: Datensatznummer des gefundenen Satzes. Es wird auf diesen Datensatz
positioniert. Wurde keiner gefunden, ist das Ergebnis 0.
Mir dem optionalen Parameter N kann die Suchgenauigkeit erhöht werden: Ist N gleich 0,
funktioniert die Funktion so, als wäre N nicht vorhanden: S2 muß irgendwo im Feld
vorhanden sein. Bei 1 muß das gesuchte Feld mit S2 beginnen und bei 2 muß der gesuchte
Eintrag dem Suchwort S2 exakt entsprechen. Groß-/Kleinschreibung spielt allerdings keine
Rolle.
Siehe auch: @dbFind
Seite 208
RGH-PROFAN²
Seite 209
RGH-PROFAN²
@dbUndelete()
Ergebnis : LongInt - Nummer des Datensatzes.
Die Löschmarkierung wird wieder entfernt.
@dbUse(#N)
N : Integer - Tabellenkennzeichen (1 - 15)
Ergebnis : LongInt - Anzahl der Sätze in der Tabelle
Die Datenbanktabelle mit der Kennung N wird zur aktuellen Datenbanktabelle. Alle weiteren
Datenbankbefehle und -funktionen beziehen sich auf diese Tabelle.
@Del$(S,N1,N2)
S : String
N1 : Wert - Position
N2 : Wert - Zeichenzahl
Ergebnis: String
Ab der Position N1 werden N2 Zeichen aus dem String entfernt.
@DeleteChoice(N1,N2)
N1: Integer - Handle der AuswahlBox
N2: Integer - Nr. des Eintrages (1. Zeile = 0)
Ergebnis: Integer - Erfolg
Der String mit dem Index N2 wird aus der Auswahlbox N1 entfernt. Dabei ist zu
berücksichtigen, daß die erste Zeile den Index 0 hat.
@DeleteString(N1,N2)
N1: Integer - Handle der Listbox
N2: Integer - Nr. der Zeile (1. Zeile = 0)
Ergebnis: Integer - Erfolg
Der String mit dem Index N2 wird aus der Listbox N1 entfernt. Dabei ist zu berücksichtigen,
daß die erste Zeile den Index 0 hat.
Seite 210
RGH-PROFAN²
@DestroyWindow(N)
N : Integer - Handle eines Fensterobjektes
Ergebnis : Integer - 1=Erfolg / 0=Mißerfolg
Das Fenster oder Fensterobjekt mit dem Handle N wird entfernt. War die Aktion erfolgreich,
ist das Ergebnis 1 ansonsten ist es 0.
@DiskFree(S)
S : String - Laufwerksbezeichnung
Ergebnis: LongInt
Das Ergebnis ist der freie Speicher auf Laufwerk S in Byte. Ist das Ergebnis z.B. 2024, so
sind noch 2 kB frei. Ist das Laufwerk nicht vorhanden oder nicht lesbar, ist das Ergebnis 0.
Beispiel:
Print @DiskFree("C:");" Bytes frei"
@DiskSize(S)
S : String - Laufwerksbezeichnung
Ergebnis: Wert
Das Ergebnis ist der Gesamtspeicher auf Laufwerk S in kB. Ist das Ergebnis z.B. 43000000,
so hat das Laufwerk ca. 43000 kB bzw. ca. 43 MB. Ist das Laufwerk nicht vorhanden oder
nicht lesbar, ist das Ergebnis 0. Beispiel:
Print @DiskSize("C:");" Bytes"
@Div&(N1,N2)
N1 : Wert
N2 : Wert
Ergebnis: Integer / LongInt
Ganzzahliges Ergebnis der Division von N1 durch N2.
@Div(N1,N2)
N1 : Wert
N2 : Wert
Ergebnis: Wert
Ergebnis der Division von N1 durch N2.
Bei PROFAN 1.x-Programmen sollte vor dem Neucompilieren überall das @Div durch
@Div& ersetzt werden, da PROFAN 1.x nur ganzzahlige Rechenoperationen beherrschte.
Seite 211
RGH-PROFAN²
@DToC$(S)
S : String - Datum im Datenbank-Format
Ergebnis : String - Datum im landespezifischen Format
Da Datumsfelder das Datum in der Form "JJJJMMTT" speichern, was für Vergleiche ganz
hervorragend ist, wandelt diese Funktion das Datum S vom Datenbankformat in das lesbare
Format (z.B. "TT.MM.JJJJ") um. Dabei werden die nationalen Einstellungen in der WIN.INI
berücksichtigt.
Auch die Funktion @GETFDATE$ hat als Ergebnis das Datum im Datenbankformat.
Seite 212
RGH-PROFAN²
@EditBox(S,N)
S - String: Überschrift des Editier-Dialoges
N - Integer: Schriftart
Ergebnis: Integer
Ab Version 3.2 gibt es einen weiteren fertigen Dialog: Den Editierdialog. S ist die Überschrift
des Dialoges und N der Modus:
1 = Proportionalschrift
2 = Courier (fester Zeichenabstand)
Editiert werden die Zeilen der Listbox-Liste. Um einen Text zu editieren, ist er zuvor in die
Listbox-Liste einzulesen. Das Ergebnis des Editiervorganges steht wiederum in der ListboxListe und kann in eine Datei geschrieben werden. Der zu editierende Text darf maximal
etwa 30 kB groß sein.
Mit den Buttons "Kopieren", "Ausschneiden" und
Editiermöglichkeiten über die Zwischenablage gegeben.
"Einfügen"
sind
die
üblichen
Wurde der Editiervorgang mit "OK" beendet, hat %BUTTON den Wert 1 und die Funktion
gibt den Wert 1 zurück, ansonsten ist %Button 2 und der Rückgabewert 0.
@Eof(#N)
N : Integer - Dateinummer (1..15)
Ergebnis: Integer (0 oder 1)
Wenn mit dem letzten Lesen aus der Datei das Ende der Datei erreicht wurde, ergibt
@Eof(#N) den Wert 1, ansonsten ist es 0.
(Wegen Kompatibilität zu PROFAN 1.x kann das # auch weggelassen werden.)
@Equ$(S1,S2)
S1 : String 1
S2 : String 2
Ergebnis: Integer (0 oder 1)
Das Ergebnis ist WAHR (1), wenn beide Strings gleich sind, UNWAHR (0), wenn die Strings
verschieden sind.
@EQU(N1,N2)
N1 : Wert - Wert 1
N2 : Wert - Wert 2
Ergebnis: Integer (0 oder 1)
Das Ergebnis ist WAHR (1), wenn beide Werte gleich sind, UNWAHR (0), wenn die Werte
verschieden sind.
Seite 213
RGH-PROFAN²
@Exp(N)
N - Wert
Ergebnis - Float
Exponentialfunktion
@ExtString$(I,N)
I : Integer - Instanz-Handle der Datei, in der der String ist
N : Integer - Nummer des Strings in der Resource
Ergebnis : String - String in der Resource
Mit dieser Funktion kann auf in Resourcen gespeicherten Srings zugegriffen werden. Das
Instanz- Handle wird bei DLLs mittels @UseDLL ermittelt und bei EXE-Dateien mittels
@WinExec. Das Handle des ausführenden Programmes ist in der Systemvariablen
%HInstance. Es ist also möglich, alle in einem Programm verwandten Strings mittels eines
Tools wie des Resource-Workshops von Borland in eine DLL zu packen. Ebenso ist es z.B.
möglich, die PROFRUN.EXE vor dem Linken entsprechend zu erweitern. Da in PROFAN²
die maximale Stringlänge 255 ist, muß darauf beim Erstellen der Resourcen geachtet
werden. Wird der String nicht gefunden, ist das Ergebnis ein Leerstring. Sinnvoll ist diese
Funktion z.B. um mehrsprachige Anwendungen zu schreiben, bei denen die Strings und
Dialoge einer Sprache jeweils in einer DLL sind.
Seite 214
RGH-PROFAN²
@FilePos(#N)
#N: Dateikennung
Ergebnis: LongInt - Aktuelle Position in der Datei
Die aktuelle Position des Dateizeigers einer mit OPENRW geöffneten Datei wird ermittelt,
wobei 0 das erste Byte der Datei bezeichnet.
@FileSize(S)
S : String - Dateiname (auch mit Pfad)
Ergebnis : LongInt - Größe der Datei in Bytes
Die Funktion ermittelt die Größe der angegebenen Datei in Bytes.
@FindFirst$(S)
S : String - Datei-Maske
Ergebnis: String
Die Funktion sucht die erste Datei im aktuellen Verzeichnis, die der Dateimaske entspricht.
Das Ergebnis ist die gefundene Datei. Handelt es sich um ein Verzeichnis, steht es in
eckigen Klammern.
@FindNext$()
Ergebnis: String
Findet die nächste Datei, die zur mit @FINDFIRST$(S) gegebenen Maske paßt. War die
Suche erfolgreich, ist %IORESULT = 0! Beispiel:
Print @FindFirst$("*.PRF")
WhileNot %IOResult
Print @FindNext$()
Wend
@FindWindow(S)
S : String - Gesuchter Fenstertitel
Ergebnis : Integer - Handle des Fensters
Gibt das Handle des Fensters zurück, dessen Überschrift mit S beginnt. Gibt es kein solches
Fenster ist das Ergebnis 0.
Seite 215
RGH-PROFAN²
@Format$(S,N)
S: String - Formatbeschreibung
N: Wert
Ergebnis: String - formatierter Wert
Die Funktion @Format$ formatiert den in N angegebenen Gleitkommawert in dem durch S
angegebenen Format. Die folgenden Formatangaben werden in dem Formatstring
unterstützt:
0
Wenn der zu formatierende Wert an der entsprechenden Stelle eine Zahl hat, so wird diese
in den Ergebnisstring kopiert. Ansonsten wird eine '0' an dieser Stelle eingesetzt.
#
Stellenplatzhalter. Wenn der zu formatierende Wert an der entsprechenden Stelle eine Zahl
hat, so wird diese in den Ergebnisstring kopiert. Ansonsten wird an diesere Stelle nichts
eingesetzt.
.
Dezimalpunkt. Das erste Auftreten des Zeichens '.' im Formatstring legt die Position des
Trennzeichens für den Dezimalteil fest; jedes weitere Vorkommen von '.' wird ignoriert. Das
tatsächlich als Dezimaltrennzeichen verwendete Zeichen wird durch die Windows-Einstellung
festgelegt.
,
Trennzeichen für die Tausenderstellen. Wenn der Formatstring ein oder mehrere ','-Zeichen
enthält, wird in dem Ergebnisstring zwischen jeder Gruppe von drei Stellen links vom
Dezimalkomma das Trennzeichen eingefügt. Die Position und Anzahl der Zeichen ',' im
Formatstring hat keinen weiteren Einfluß auf den Ergebnisstring, mit der Ausnahme, daß
hierdurch angegeben wird, daß Trennzeichen für die Tausenderstellen gewünscht sind. Das
tatsächlich als Trennzeichen verwendete Zeichen wird durch die Windows-Einstellung
festgelegt.
E+
Wissenschaftliche Notierung. Wenn in dem Formatstring einer der Strings 'E+', 'E-', 'e+' oder
'e-' vorkommen, wird die Zahl in wissenschaftlicher Notierung dargestellt. Bis zu vier Zeichen
'0' können unmittelbar auf 'E+', 'E-', 'e+' oder 'e-' folgen, um die minimale Anzahl Stellen für
den Exponenten festzulegen. Die Angaben 'E+' und 'e+' bewirken, daß für positive
Exponenten ein Pluszeichen und für negative Exponenten ein Minuszeichen eingefügt wird.
Die Angaben 'E-' und 'e-' bewirken, daß lediglich für negative Exponenten ein Minuszeichen
eingefügt wird.
'xx'
Zeichen, die von einfachen Anführungszeichen umgeben sind, werden wie angegeben
dargestellt und beeinflussen nicht die Formatierung.
Seite 216
RGH-PROFAN²
;
Trennt die Bereiche für positive und negative Werte sowie für Nullwerte im Formatstring. Um
für positive und negative Werte sowie für Nullwerte unterschiedliche Formate zu
ermöglichen, kann der Formatstring bis zu drei durch Semikolon getrennte Bereiche
enthalten.
- Ein Bereich: Der Formatstring wird auf alle Werte angewendet.
- Zwei Bereiche: Der erste Bereich wird für positive Werte und Nullwerte angewendet, der
zweite Bereich für negative Werte.
- Drei Bereiche: Der erste Bereich wird für positive Werte, der zweite Bereich für negative
Werte und der dritte Bereich für Nullwerte angewendet.
Wenn der Bereich für negative Werte oder der Bereich für Nullwerte leer ist, d.h. nichts
zwischen den Semikolons steht, die den Bereich begrenzen, wird stattdessen der Bereich für
positive Werte verwendet.
Die Position der in dem Formatstring vor dem Dezimalpunkt am weitesten links stehenden '0'
und der nach dem Dezimalpunkt am weitesten rechts stehenden '0' legt die Anzahl Stellen
fest, die in dem Ergebnisstring immer dargestellt werden.
Die zu formatierende Zahl wird immer auf so viele Dezimalstellen gerundet, wie
Stellenplatzhalter ('0' or '#') rechts vom Dezimalpunkt vorhanden sind. Wenn der
Formatstring keinen Dezimalpunkt enthält, wird der zu formatierende Wert auf die nächste
Ganzzahl gerundet.
Wenn die zu formatierende Zahl mehr Stellen links vom Dezimaltrennzeichen hat, als
Stellenplatzhalter links vom Zeichen '.' im Formatstring vorhanden sind, werden die
zusätzlichen Stellen vor dem ersten Stellenplatzhalter in dem Ergebnisstring eingefügt.
Beispiel:
PRINT @Format$("###,##0.00 ' H';"###,##0.00 ' S'",Wert!)
Wenn der Wert z.B. +1234,45 ist, würde "~~1.234,45 H" ausgegeben werden und bei -0,12
käme "~~~~~~0,12 S" heraus, wobei hier die Tilde für ein Leerzeichen steht.
@GetActiveWindow()
Ergebnis : Integer - Fenster-Handle
Die Funktion ermittelt das Handle des gerade aktiven Fensters.
@GetBValue(N)
N: Integer - Farbwert
Ergebnis: Integer - Blauanteil der Farbe
Der entsprechende Farbanteil einer Farbe wird ermittelt. Je nach Farbmodus ist es ein Wert
zwischen 0 und 31 bzw. zwischen 0 und 255. Der Farbwert kann z.B. mit der Funktion
@GetPixel ermittelt worden sein.
Seite 217
RGH-PROFAN²
@GetByte(#N)
#N: Dateikennung
Ergebnis: Integer - Wert (0...255)
Es wird ein Byte aus einer mit OPENRW geöffneten Datei gelesen. Der Dateizeiger wird auf
das nächste Byte positioniert. Zum Positionieren des Zeigers ist der Befehl SEEK zu
verwenden.
@GetCheck(N)
N : Integer - Handle des Fensterobjektes
Ergebnis : Integer - Zustand: 0=nicht aktiviert / 1=aktiviert
Die Funktion gibt den Zustand der Checkbox bzw. des Radiobuttons mit dem Handle N
zurück:
0 - Checkbox/Radiobutton ist nicht aktiviert
1 - Checkbox/Radiobutton ist aktiviert
Siehe auch: SetCheck
@GetClip$()
Ergebnis : String
Die Funktion liest Text aus dem Clipboard (max. 255 Zeichen). Die Zwischenablage wird bei
Lesen nicht gelöscht. Dazu ist der Befehl ClearClip zu verwenden.
Sie auch: PutClip
@GetCount(N)
N: Integer - Handle der Listbox
Ergebnis: Integer - Anzahl der Elemente
Die Anzahl der Elemente (Zeilen) einer Listbox wird ermittelt. Bitte berücksichtigen Sie, daß
das erste Element der Listbox den Index 0 hat und somit der Index des letzten Elementes
um 1 niedriger ist, als die ermittelte Anzahl der Elemente!
@GetCursel(N)
N: Integer - Handle der Listbox
Ergebnis: Integer - aktuelle Position in der Listbox
Die Position des Kursors (Balkens) in der Listbox N wird ermittelt. Die erste Zeile hat den
Index 0.
Seite 218
RGH-PROFAN²
@GetDir$(S)
S : Laufwerkskennzeichen
Ergebnis: String (Pfad)
Der Pfad des angegebenen Laufwerks wird ermittelt, wobei "@" für das aktuelle Laufwerk
steht. Beispiel:
Let CPfad$=@GetDir$("C:")
Let Pfad$=@GetDir$("@")
@GetEnv$(S)
S : String - Name der Variablen
Ergebnis : String - Inhalt der Variablen
Die Funktion liest die entsprechenden Environmentvariable aus. Beispiel:
LET Pfad$ = @GetEnv$("PATH")
@GetFAttr(#N)
#N: Dateikennung
Ergebnis: Integer - Attribut
Das Attribut einer Datei wird ermittelt. Der Dateikennung muß zuvor mit ASSIGN eine Datei
zugewiesen worden sein. Die Datei darf nicht geöffnet sein. Die Werte für Attribute:
$01 = ReadOnly
$02 = Hidden
$04 = SystemDatei
$08 = Label
$10 = Directory-Eintrag
$20 = Archiv
Werden mehrer Attribute verwandt, so sind sie zu addieren. Eine Systemdatei, die zusätzlich
versteckt (hidden) ist, hat demzufolge $06 als Attribut.
@GetFDate$(#N)
#N: Dateikennung
Ergebnis: String- Datum im Format "JJJJMMTT"
Das Datum der Datei wird ermittelt. Der Dateikennung muß zuvor mit ASSIGN eine Datei
zugewiesen worden sein. Die Datei muß (z.B. mit RESET) geöffnet sein.
Seite 219
RGH-PROFAN²
@GetFileSize(#N)
#N: Dateikennung
Ergebnis: LongInt - Größe der Datei in Bytes
Die aktuelle Größe einer mit OPENRW geöffneten (!) Datei in Bytes wird ermittelt. Um die
Größe einer ungeöffneten Datei zu ermitteln ist die Funktion @FileSize zu ermitteln. Der
Vorteil von @GetFileSize liegt darin, daß die Größe einer gerade zum Bearbeiten geöffneten
Datei ermittelt werden kann.
@GetFocus(N)
N : Integer - Handle eines Fensterobjektes
Ergebnis : Integer (0 oder 1)
Die Funktion ermittelt, ob das Fensterobjekt mit dem Handle N den Focus hat. Wenn es ihn
hat, ist das Ergebnis 1 ansonsten ist es 0. Um zu ermitteln, wer den Focus hat, ist die
Systemvariable %GETFOCUS zu verwenden.
Wurde während eines WAITINPUT F1 gedrückt, während der Fokus in einer Dialogbox bzw.
auf einem Diologelement ist, steht in %GetFocus der negative wert des Handles.
@GetGValue(N)
N: Integer - Farbwert
Ergebnis: Integer - Grünanteil der Farbe
Der entsprechende Farbanteil einer Farbe wird ermittelt. Je nach Farbmodus ist es ein Wert
zwischen 0 und 31 bzw. zwischen 0 und 255. Der Farbwert kann z.B. mit der Funktion
@GetPixel ermittelt worden sein.
@GetHandle(H,N)
H
N
: Integer - Handle der Dialoges, der das Element enthält
: Integer - Nummer des Dialogelementes im Dialog
Ergebnis : Integer - Handle des Dialogelementes
Hiermit wird aus der Identifikationsnummer eines Dialogelementes und dem Dialog zu dem
es gehört das Handle ermittelt. Beim Erstellen eines Dialoges mit einem Resourcen-Editor
wird jedem Dialogelement ein eindeutiger Wert zugewiesen: die Identifikationsnummer. Zur
Laufzeit interessiert uns aber das eindeutige Windows-Handle des Dialogelementes, denn
dieses wird von den PROFAN²- Funktionen und den Windows-Messages zur Identifikation
benutzt. Da dieses Handle erst beim Erzeugen des Dialoges (mittels der Funktion
@CreateExtDialog) vergeben wird, können wir es auch erst zur Laufzeit nach dieser
Funktion, mit der der Dialog auf den Bildschirm gebracht wird, ermitteln. Dazu dient die
Funktion @Gethandle.
Ein Beispiel findet sich in der Beschreibung der Funktion @CreateExtDialog. (Übrigens:
Auch PROFAN² selbst vergibt jedem mit @Create... erzeugten Dialogelement eine solche
Identifikationsnummer. Das erste Element im Programm hat die Nummer 1000. Von da an
wird bei jedem @Create... um 1 hochgezählt.)
Seite 220
RGH-PROFAN²
@GetKey$()
Ergebnis: String (1 Zeichen)
Wartet auf einen Tastendruck und gibt das Ergebnis zurück.
@GetLine$(N1,N2)
N1: Integer - Handle der EditBox
N2: Integer - Nr. des Zeile (1. Zeile = 0)
Ergebnis: String - Zeile N2 der EditBox
Die Zeile N2 der mehrzeiligen Editierbox N1 wird ermittelt.
@GetLineCount(N)
N: Integer - Handle der EditBox
Ergebnis: Integer - Anzahl der Zeilen
Die Anzahl der Zeilen eines mehrzeiligen Editierfeldes wird ermittelt. Bitte berücksichtigen
Sie, daß das erste Element den Index 0 hat und somit die letzte Zeile einen um 1 niedrigeren
Index hat, als die ermittelte Anzahl der Zeilen!
@GetPixel(X,Y)
X : Integer - X-Koordinate
Y : Integer - Y-Koordinate
Ergebnis : Integer - Farbwert (RGB)
Farbwert des Bildpunktes an Position x,y.
ACHTUNG: Je nach Grafikmodus weicht dieser Wert von dem in SetPixel übergebenen
Farbwert ab, da z.B. im 16-Farbmodus ein Punkt nur eine von 16 Farben haben
kann.
@GetRValue(N)
N: Integer - Farbwert
Ergebnis: Integer - Rotanteil der Farbe
Der entsprechende Farbanteil einer Farbe wird ermittelt. Je nach Farbmodus ist es ein Wert
zwischen 0 und 31 bzw. zwischen 0 und 255. Der Farbwert kann z.B. mit der Funktion
@GetPixel ermittelt worden sein.
Seite 221
RGH-PROFAN²
@GetString$(N1,N2)
N1: Integer - Handle der Listbox
N2: Integer - Nr. des Eintrages (1. Zeile = 0)
Ergebnis: String - Zeile N2 der Listbox
Die Zeile mit dem Index N2 wird aus der Listbox N1 ausgelesen.
@GetText$(N)
N : Integer - Handle des Fensterobjektes
Ergebnis : String - Text des Fensterobjektes
Es wird der Text des Fensterobjektes mit dem Handle N ermittelt. Im Falle eines
Eingabefeldes ist es der eingegebene Text, ansonsten die Fensterüberschrift, der Text des
Buttons oder der Text neben der Checkbox oder dem Radiobutton. (Kurz: Der Text der
mittels der @CREATE...-Funktion oder dem SETTEXT-Befehl in S an das Fensterobjekt
übergeben wurde.)
@GetUsage(N)
N : Integer - Handle eines Programmes
Ergebnis: Integer - Anzahl der Instanzen
N ist das Handle der mit @WINEXEC gestarteten Anwendung. Das Ergebnis gibt an, wie oft
diese Anwendung gestartet wurde und wird 0, wenn die letzte Instanz der Anwendung
geschlossen wird. So kann man z.B. ein Programm starten und solange in einer Schleife
verharren, bis das Programm beendet wird:
...
LET X%=@WINEXEC("NOTEPAD.EXE",3)
WHILE @GETUSAGE(X%)
WEND
...
HINWEIS. Die dieser Funktion zugrundeliegende API-Funktion ist in der 32-Bit-API von
Windows 95 nicht mehr enthalten. Um sie trotzdem im 32-Bit-PROFAN² zu implementieren,
wurde eine undokumentierte Windowsfunktion benutzt, sodaß damit zu rechnen ist, daß
diese Funktion unter Windows NT nicht erwartungsgemäß funktioniert. Für obiges Beispiel ist
daher die Funktion @WINEXECWAIT vorzuziehen.
@GT(N1,N2)
N1 : Wert - Wert 1
N2 : Wert - Wert 2
Ergebnis: Wert (0 oder 1)
Das Ergebnis ist WAHR (1), wenn Wert 1 größer als (Greater Than) Wert 2 ist.
Seite 222
RGH-PROFAN²
@GT$(S1,S2)
S1 : String 1
S2 : String 2
Ergebnis: Integer (0 oder 1)
Das Ergebnis ist WAHR (1), wenn String 1 größer als (Greater Than) String 2 ist.
@Height(H)
H
: Integer - Handle des Fensters, Dialoges, Dialogelementes
Ergebnis : Integer - Höhe des Elementes innerhalb des Rahmens
Oftmals benötigt man zum Zeichnen die Größe des Fensters bzw. Dialoges innerhalb des
Rahmens (so einer vorhanden ist). Diese Fläche wird auch der Client genannt. Bei einem
Fenster schließt diese Fläche Menü und Titelleiste nicht mit ein, sondern es wird nur der Teil
ausgemessen, der auch tatsächlich zum Malen, Schreiben, etc. genutzt werden kann.
Seite 223
RGH-PROFAN²
@IconCount(S)
S - String: Dateiname (mit Pfad)
Ergebnis: Integer - Anzah der Icons
Die Funktion liefert die Anzahl der in S enthaltenen Icons zurück. S kann sowohl eine EXEDatei, eine DLL als auch eine Icon-Datei sein. Beispiel:
Let Anz% = @IconCount("PROGMAN.EXE")
@If(N1,N2,N3)
N1 : Wert - Bedingung
N2 : Wert - Ergebnis bei erfüllter Bedingung
N3 : Wert - Ergebnis bei nicht erfüllter Bedingung
Ergebnis : Wert, abhängig von der Bedingung
In Anlehnung an C gibt es das IF auch als Funktion. Die Funktion @IF hat drei Argumente:
Das erste Argument ist die Bedingung; das zweite Argument ist der Wert, der zurückgegeben
wird, wenn die Bedingung erfüllt ist und das dritte Argument ist schließlich der Wert, der bei
unerfüllter Bedingung zurückgegeben wird. Beispiele:
LET Text$ = @IF(@Equ(A%,1), "A ist gleich 1", \
"A ist ungleich 1")
PRINT Text$
LET A% = @IF(@Gt(A%,1000),@Add(A%,200),@Add(A%,50))
PRINT A%
Im zweiten Beispiel wird zu A% 200 addiert wenn es größer als 1000 ist; im anderen Fall
kommen nur 50 dazu.
@Inkey$()
Ergebnis: String (1 Zeichen)
Gibt als Ergebnis das Zeichen der aktuell gedrückten Taste zurück.
@Inp(N)
N : Integer - Port-Adresse
Ergebnis : Integer - 16-Bit-Wert an Port N
Es wird ein Datenwort (16 Bit bzw. 2 Byte) am Input-Port N (und N+1) gelesen. Das
niederwertige Byte liegt an Port N und das höherwertige an Port N+1 an.
ACHTUNG: Man sollte wissen, was man tut, da unter Windows nicht alle Port-Adressen
gelesen werden können. Ein Absturz von Windows mit Datenverlust ist dadurch möglich.
HINWEIS: Unter Windows NT sind direkte Zugriffe auf die Hardware nicht gestattet. Die
Funktionen @INP und @INPW sind hier zu vermeiden.
Seite 224
RGH-PROFAN²
@InpB(N)
N : Integer - Port-Adresse
Ergebnis : Integer - 8-Bit-Wert (Byte) an Port N
Es wird ein Byte (8 Bit) am Input-Port N gelesen.
ACHTUNG: Man sollte wissen, was man tut, da unter Windows nicht alle Port-Adressen
gelesen werden können. Ein Absturz von Windows mit Datenverlust ist dadurch möglich.
HINWEIS: Unter Windows NT sind direkte Zugriffe auf die Hardware nicht gestattet. Die
Funktionen @INP und @INPW sind hier zu vermeiden.
@Input$(S1,S2,S3)
S1 - String: Prompt (Frage)
S2 - String: Fensterüberschrift
S3 - String: Vorgabestring bzw. Vorgabewert
Ergebnis: String bzw. Wert (Eingabe)
Eine Dialogbox zur Eingabe eines Strings wird auf den Bildschirm gebracht. Diese Funktion
sollte wo möglich anstelle des INPUT-Befehles verwandt werden.
Ab PROFAN² 2.5 kann sowohl die Vorgabe als auch das Ergebnis numerisch sein. Die
Funktion kann so zur Eingabe von Strings und numerischen Werten verwandt werden.
Beispiele:
Let Ort$=@Input$("Ort eingeben:,"Test","Köln")
Let Z&=@Input$("Neuer Wert:","Test",Z&)
@Ins$(S1,S2,N)
S1 : String
S2 : String
N : Wert
Ergerbnis: String
Der String S1 wird in S2 an Position N eingegefügt.
Seite 225
RGH-PROFAN²
@InsertString(N1,N2,S)
N1: Integer - Handle der Listbox
N2: Integer - Position (gewünschte Zeile)
S: String - einzufügende Zeile
Ergebnis: Integer - Position des eingefügten Strings
Die Zeile S wird an der Position N2 in der Listbox N1 eingefügt. Diese Funktion macht
natürlich nur Sinn bei einer unsortierten Listbox. Hat N2 den Wert -1 wird die Zeile am Ende
der Listbox angehängt.
@Instr(S1,S2)
S1 : String
S2 : String
Ergebnis: Wert
Das Ergebnis gibt an, an welcher Position S1 in S2 vorkommt. Kommt S1 in S2 nicht vor, ist
das Ergebnis 0.
@Int(N)
N : Wert
Ergebnis : Integer / LongInt
Ganzzahliger Anteil von N. Es wird nicht gerundet. (Gerundet wird bei Beschränkung der
auszugebenden Stellen mit NUMWIDTH.)
Seite 226
RGH-PROFAN²
@KeyIn(S)
S : String
Ergebnis: Wert (0 oder 1)
Das Ergebnis ist dann 1, wenn die zuletzt gedrückte Taste im String S vorkommt. Beispiel:
WaitKey
Case @KeyIn("AaBb"):Print "A oder B"
Seite 227
RGH-PROFAN²
@Left$(S,N)
S : String
N : Anzahl Zeichen
Ergebnis : String
Die N linken Zeichen des Strings werden zurückgegeben.
@Len(S)
S : String
Ergebnis: Wert
Länge des Strings S
@Lg(N)
N : Wert > 0
Ergebnis : Wert
Dekadischer Logarithmus zum Wert N.
@List!(N)
N : Integer - Index (0 .. 32767 bzw. 16380)
Ergebnis: Float
Das Ergebnis ist der N. Eintrag der Float-Liste. Die Liste wird mit dem Befehl LIST! gefüllt.
@List$(N)
N : Integer - Index (0 .. 32767 bzw. 16380)
Ergebnis: String
Das Ergebnis ist der N. Eintrag der Stringliste. Die Liste wird mit dem Befehl LIST$ gefüllt.
@List%(N)
N : Integer - Index (0 .. 32767 bzw. 16380)
Ergebnis: Integer
Das Ergebnis ist der N. Eintrag der Integerliste. Die Liste wird mit dem Befehl LIST% gefüllt.
Seite 228
RGH-PROFAN²
@List&(N)
N : Integer - Index (0 .. 32767 bzw. 16380)
Ergebnis: LongInt
Das Ergebnis ist der N. Eintrag der LongInt-Liste. Die Liste wird mit dem Befehl LIST&
gefüllt.
@ListBox$(S,N)
S : String - Fenster-Überschrift
N : Wert - Typ der Listbox (1 .. 8)
Ergebnis: Ausgewählter String
Der Inhalt der ListBox-Liste wird zur Auswahl (oder zum Durchblättern) angeboten. Der
zweite Parameter gibt an, in welcher Form die ListBox angezeigt werden soll:
1
2
3
4
5
6
7
8
- groß - unsortiert - Systemschrift
- groß - unsortiert - Courier 10
- groß - sortiert - Systemschrift
- groß - sortiert - Courier 10
- klein - unsortiert - Systemschrift
- klein - unsortiert - Courier 10
- klein - sortiert - Systemschrift
- klein - sortiert - Courier 10
Die große (unsortierte) ListBox eignet sich insbesondere zur Darstellung von Texten. Diese
werden eingelesen und dann angezeigt. Beispiel:
ClearList
AddFiles "*.BMP"
Let Wahl$=@ListBox$("Wähle Bild:",7)
LoadBmp Wahl$,10,10
Die Listbox-Liste wird ADDFILES, ADDWINDOWS und ADDSTRING gefüllt und mit
CEARLIST geleert; %GETCOUNT enthält die Anzahl der Einträge und mit
@LISTBOXITEM$ kann man einen einzelnen Eintrag auslesen. Siehe auch das Demo
"Schnelleinstieg"!
@ListBoxItem$(N)
N : Integer (0 ... 9999)
Ergebnis: String
Der N-te Eintrag der ListBox-Liste wird ermittelt.
Seite 229
RGH-PROFAN²
@Ln(N)
N : Wert > 0
Ergebnis : Wert
Natürlicher Logarithmus zum Wert N.
@LoadFile$(S1,S2)
S1 : String - Überschrift
S2 : String - Dateimaske (mit Pfad)
Ergebnis: Dateiname (mit Pfad)
Es wird eine Dateiauswahlbox zum Laden (Öffnen) mit der Überschrift S1 geöffnet. Das
Ergebnis ist die gewählte Datei (mit Pfad), die geöffnet werden kann. Beispiel:
LET NAME$=@LOADFILE$("ÖFFNE:","*.EXE")
In der 32-Bit-Version werden die Systemdialoge zum Laden und Speichern verwandt. Diese
erlauben den Einsatz mehrerer Dateifilter. Will man dieses Feature nutzen, kann man
mehrere Dateifilter, die jeweils aus Beschreibung und Endung(en) bestehen, kombinieren.
Wollten wir in unserem Beispiel neben *.EXE-Dateien auch *.PIF- und *:BAT-Dateien öffnen,
könnte die Zeile wie folgt aussehen:
Let Name$ = @LoadFile$("ÖFFNE","Programme|*.EXE;*.PIF|Batch|*.BAT")
Der senkrechte Strich wird mit [AltGr]+[<] erreicht.
@Long(V,A)
V: Bereichsvariable
A: Integer - Adresse
Ergebnis: LongInt - Wert
Diese Funktion ermittelt der Wert des 32-Bit-Wortes (4 Byte) an der Adresse (Offset) A in der
Bereichsvariablen V. Ist A außerhalb des mit DIM eingestellten Bereiches von V, erfolgt eine
Fehlermeldung.
@LongName$(S)
S: String - Mit @ShortName$ ermittelter Kurz-Name (8.3) einer Datei (incl. Pfad)
Ergebnis: langer Name von Pfad und Datei
Diese Funktion ermittelt zu einem kurzen Dateinamen (System 8.3) den dazugehörigen
langen Dateinamen. Dabei darf der Dateiname auch einen Pfad enthalten. Wenn die Datei
nicht (mehr) existiert wird ein Leerstring zurückgegeben. (Unter Windows 3.x, bzw. wenn die
langen Dateinamen mit SetLFN 0 ausgeschaltet sind, wird immer der String S
zurückgegeben.)
Seite 230
RGH-PROFAN²
@Lower$(S)
S : String
Ergebnis: String
Der String S wird komplett in Kleinbuchstaben umgewandelt, wobei die nationalen
Sonderzeichen (z.B. die deutschen Umlaute) korrekt berücksichtigt werden.
@LT(N1,N2)
N1 : Wert 1
N2 : Wert 2
Ergebnis: Wert (0 oder 1)
Das Ergebnis ist WAHR (1), wenn Wert 1 kleiner als (Less Than) Wert 2 ist.
@LT$(S1,S2)
S1 : String 1
S2 : String 2
Ergebnis: Integer (0 oder 1)
Das Ergebnis ist WAHR (1), wenn String 1 kleiner als (Less Than) String 2 ist.
Seite 231
RGH-PROFAN²
@MCISend$(S)
S : String - MCI-Kommando
Ergebnis: String (MCI-Ergebnis)
Es wird der String S als Kommando gesandt. Das Ergebnis (oder ein Fehler) wird
zurückgegeben. Beispiele:
Ausgabe einer "WAV"-Datei:
@MCISend$("open gong.wav type \
waveaudio alias gong")
@MCISend$("play gong wait") 'Datei spielen
@MCISend$("close gong") '... schließen
Das "wait" veranlaßt den PC zu warten, bis der Vorgang beendet ist.
WAV-Datei per Mikro aufnehmen:
@MCISend$("open new type waveaudio \
alias test")
'Neue WAV-Datei
@MCISend$("set test time format \
milliseconds") 'Zeitformat msec
@MCISend$("record test from 0 to \
5000 wait")
'5 sec Aufnahme
@MCISend$("Play test from 0 wait")
'abspielen
@MCISend$("save test test.wav")
'speichern
CD (Titel 3 - 5) abspielen:
@MCISend$(open cdaudio alias cd")
Print "Länge: ";@MCISend$\
("status cd length")
Print "Titelzahl: ";@MCISend$\
("status cd number of tracks")
@MCISend$("set cd time format tmsf")
@MCISend$("play cd from 3 to 5 wait")
@MCISend$("stop cd")
@MCISend$("close cd")
Auf diese Weise lassen sich alle Multimediageräte und auch Video für Windows steuern.
Näheres finden Sie in der Anleitung und in der Fachliteratur.
@MenuItem(N)
N : Wert - Menü-Kennzeichen
Ergebnis: Wert (1 oder 0)
Wenn der aktuell gewählte Menüpunkt mit N (0 bis 32766) übereinstimmt, ist das Ergebnis
1, anderenfalls ist es 0. Ist N gleich 0, dann ist das Ergebnis 1, wenn kein Menüpunkt
angewählt wurde. 254 steht für die Anwahl des Copyright-Zeichens.
Seite 232
RGH-PROFAN²
@MessageBox(S1,S2,N)
S1 : String - Meldungstext
S2 : String - Überschrift
N : Integer - Art der MessageBox
Ergebnis - Integer: gedrückter Knopf
Eine MessageBox wird auf dem Bildschirm gebracht. N setzt sich zusammen aus BUTTONS
+ ICON + DEFAULT + FENSTERART.
Werte für BUTTON:
0
1
2
3
4
5
- OK
- OK Abbrechen
- Abbrechen Wiederholen Ignorieren
- Ja Nein Abbrechen
- Ja Nein
- Wiederholen Abbrechen
Werte für ICON:
0
16
32
49
64
- Kein Icon
- STOP
- "?"
- "!"
- "i"
Werte für DEFAULT (Der Wert gibt an, welcher Knopf defaultmäßig angewählt ist):
0
256
512
- erster Knopf
- zweiter Knopf
- dritter Knopf
Werte für FENSTERART:
0
4096
- "normales" Fenster.
- großes, nicht verschiebbares "Fehler"-Fenster.
Das Ergebnis ist der gedrückte Knopf:
1
2
3
4
5
6
7
- OK
- Abbrechen (Cancel)
- Abbrechen (Abort)
- Wiederholen
- Ignorieren
- Ja
- Nein
Seite 233
RGH-PROFAN²
@Mid$(S,N1,N2)
S : String
N1 : Integer - Position
N2 : Integer - Anzahl
Ergebnis: String
Das Ergebnis ist ein String, der N2 Zeichen ab Position N1 aus String S enthält.
@Mod(N1,N2)
N1 : Integer
N2 : Integer
Ergebnis: Integer
Das Ergebnis ist N1 modulo N2.
@MkStr$(S,N)
S : String
N : Anzahl Wiederholungen
Ergebnis : String
Es wird ein String zurückgegeben der N mal aus String S besteht.
@MoveListToChoice(N)
N: Integer - Handle der AuswahlBox
Ergebnis: Integer - Erfolg
Der Inhalt der Listbox-Liste (für die vorgefertigten Listbox-Dialoge) wird in die AuswahlBox N
kopiert.
@MoveListToEdit(N)
N: Integer - Handle der EditBox
Ergebnis: Integer - Erfolg
Der Inhalt der Listbox-Liste (für die vorgefertigten Listbox-Dialoge) wird in die EditBox N
kopiert.
@MoveListToList(N)
N: Integer - Handle der ListBox
Ergebnis: Integer - Erfolg
Seite 234
RGH-PROFAN²
Der Inhalt der Listbox-Liste (für die vorgefertigten Listbox-Dialoge) wird in die Listbox N
kopiert. So kann zum Beispiel die Listboxliste mit Befehlen wie ADDWINDOWS, ADDFILES
oder ADDFONTS gefüllt werden und dann in eine beliebige Listbox kopiert werden.
Seite 235
RGH-PROFAN²
@Mouse(X1,Y1-X2,Y2)
X1,Y1 : Integer - linke obere Ecke
X2,Y2 : Integer - rechte untere Ecke
Ergebnis: Integer (0 oder 1)
Das Ergebnis ist 1, wenn beim letzten Mausklick die Maus im angegeben Bereich war.
Beispiel:
WaitMouse
Case @Mouse(10,10-60,60):Gosub "Info"
@Mul(N1,N2)
N1 : Wert
N2 : Wert
Ergebnis: Wert
Multiplikation von N1 mit N2.
Seite 236
RGH-PROFAN²
@Neq(N1,N2)
N1 : Wert - Wert 1
N2 : Wert - Wert 2
Ergebnis: Integer (0 oder 1)
Das Ergebnis ist UNWAHR (0), wenn beide Werte gleich sind, WAHR (1), wenn die Werte
verschieden sind.
@Neq$(S1,S2)
S1 : String 1
S2 : String 2
Ergebnis: Integer (0 oder 1)
Das Ergebnis ist UNWAHR (0), wenn beide Strings gleich sind, WAHR (1), wenn die Strings
verschieden sind.
@Not(N)
N : Wert
Ergebnis: Integer (0 oder 1)
Das Ergebnis ist 1, wenn N den Wert 0 hat, ansonsten ist es 0.
Seite 237
RGH-PROFAN²
@OemToAnsi$(S)
S : String
Ergebnis: String
Der String S wird von ASCII-Code in den Ansi-Code umgewandelt.
Diese Umwandlungen betreffen insbesondere die deutschen Sonderzeichen. Der ASCIICode wird unter DOS verwandt, der ANSI-Code unter Windows.
@OpenCom(COMx,N1,N2)
COMx: String - Bezeichnung der Schnittstelle
(z.B. "COM1" oder "COM2")
N1: Integer - Puffergröße für zu sendende Daten
N2: Integer - Puffergröße für zu empfangene Daten
Ergebnis: Integer - Schnittstellen-Handle (größer oder gleich 0)
bei Werten kleiner als 0 ist ein Fehler aufgetreten
Die Schnittstelle wird mit der aktuellen Einstellung initialisiert und geöffnet. Die Puffergröße
sollte so bemessen sein, daß die zu sendenden und zu empfangenden Daten Platz finden.
Also nicht zu geizig mit den Bytes sein. Mit @SETCOM und @SETCOMEXT können
anschließend die Parameter der Schnittstelle exakt eingestellt werden.
@Or(N1,N2)
N1 : Wert
N2 : Wert
Ergebnis: Integer
ODER-Funktion: Das Ergerbnis ist ungleich 0, wenn N1 ODER N2 (oder beide) ungleich 0
sind. Anders ausgedrückt: Es ist nur dann 0, wenn beide Argumente 0 sind.
@Ord(S)
S : String
Ergebnis: Integer
Der ANSI-Code des ersten Zeichens von S.
Seite 238
RGH-PROFAN²
@Par$(N)
N : Integer - Parameter-Nummer
Ergebnis: String - Parameter
Die Kommandozeilenparameter werden ausgelesen. Die Anzahl wird mit %PARCOUNT
festgestellt.
Aufrufmöglichkeiten:
Interpreter:
PROFAN <name.prf> <par2> <par3> ...
Runtime (bzw. .EXE-Datei als Runtime):
bzw.
PROFRUN <name.prc> <par2> <par3> ...
<name.exe> <name.prc> <par2> <par3> ...
.EXE-Datei:
<name.exe> <par1> <par2> <par3> ...
Bei der .EXE-Datei versucht das integrierte Runtime-Modul zunächst, den ersten Parameter
<par1> als PROFAN²-Compilat (*.prc) zu interpretieren. Handelt es sich um eine solches,
wird es ausgeführt, ansonsten das Programm selbst. Eine PRC-Datei wird auch als solche
erkannt, wenn sie eine andere Endung hat.
@Pi()
Ergebnis: Float - PI
Die Kreitzahl PI (3,41...)
@Pow(N1,N2)
N1 : Wert
N2 : Wert
Ergebnis : Wert
Potenzfunktion. Das Ergebnis ist N1 hoch N2 (in BASIC: N1^N2).
Seite 239
RGH-PROFAN²
@PostMessage(N1,N2,N3,N4)
N1 : Integer - Handle des Empfängers
N2 : Integer - Nummer der Meldung
N3 : 16-Bit: Integer - 16-Bit meldungsabhängige Informationen
32-Bit: Longint - 32-Bit meldungsabhängige Informationen
N4 : LongInt oder Bereich - 32-Bit meldungsabhängige Informationen
Ergebnis : Integer - 1 = Erfolg, 0 = Mißerfolg
Es wird eine Meldung an das Fenster bzw. Fensterobjekt mit dem Handle N1 gesandt. N2
bezeichnet die Meldung. Die Werte N3 und N4 sind von der gewählten Meldung abhängig.
Im Gegensatz zu @SendMessage wird hier nicht auf das Ergebnis gewartet, sondern direkt
mit einer Erfolgsmeldung (oder auch nicht) zum Programm zurückgekehrt. Erfolg heißt
lediglich, daß die Meldung abgesetzt werden konnte.
Eine Liste mit den Nummern der Meldungen findet sich im Anhang.
@Pwd$(S)
S: String - zu ver-/entschlüsselnder Text
Ergebnis: String - ent-/verschlüsselter Text
Mit dieser Funktion kann ein String verschlüsselt werden. Durch erneuten Aufruf wird der
String wieder entschlüsselt. Damit das Ganze funktioniert, muß mit dem Befehl PASSWORD
ein Paßwort definiert sein. Selbstverständlich muß zum Entschlüsseln das gleiche Paßwort
eingestellt sein wie beim Verschlüsseln. Ist kein Paßwort eingestellt beziehungweise ist es
ein Leerstring bewirkt die Funktion nichts. Die Funktion ist derart gestaltet, daß die
Sortierreihenfolge der Strings sich nicht ändert. Sie kann also auch in Zusammenhang mit
dBase-Dateien benötigt werden.
HINWEIS: Diese Verschlüsselung erschwert zwar den Zugriff auf die Daten, ist aber (noch)
nicht unknackbar!
Seite 240
RGH-PROFAN²
@ReadCom(N1,N2)
N1: Integer - Schnittstellenhandle
N2: Integer - Anzahl der zu lesenden Zeichen
Ergebnis: String - die empfangenen Zeichen
Der String wird aus der Schnittstelle gelesen, maximal jedoch N2 Zeichen. Ist der
Ergebnisstring ein Leerstring, lagen entweder keine Daten an oder es trat ein Fehler auf. Der
Fehler kann mit @COMERROR ermittelt werden. Das sollte nach jedem Aufruf von
@WRITECOM geschehen! Die Schnittstelle muß mit @OPENCOM geöffnet worden sein. N
ist das dabei ermittelte Handle.
Siehe auch: @WriteCom, @SetCom, @CloseCom
@ReadIni$(S1,S2,S3)
S1 - String: Dateiname / Registry-Klasse (32 Bit)
S2 - String: Anwendungsname (Rubrik) / Pfad in der Regsitry (32 Bit)
S3 - String: Eintrag / Schlüssel
Ergebnis: String (Wert des Eintrages)
Ein Wert aus einer INI-Datei wird gelesen. Ermittlung des Druckers:
Let Drucker$=@ReadIni$("WIN.INI",\
"Windows","Device")
In der 32-Bit-Version ist es zusätzlich möglich, Werte aus der Registry (Registrierdatenbank)
auszulesen. In diesem Fall muß als erster Parameter die Klasse mit "HKEY_0" bis "HKEY_6"
angegeben werden:
HKEY_CLASSES_ROOT
HKEY_CURRENT_USER
HKEY_LOCAL_MACHINE
HKEY_USERS
HKEY_PERFORMANCE_DATA
HKEY_CURRENT_CONFIG
HKEY_DYN_DATA
=
=
=
=
=
=
=
KKEY_0
HKEY_1
HKEY_2
HKEY_3
HKEY_4
HKEY_5
HKEY_6
Der zweite Parameter ist dann der komplette "Pfad" zum Eintrag. Der dritte Parameter ist der
Schlüssel (Key), der ausgelesen werden soll. Ist der Pfad in der Registry nicht vorhanden,
erfolgt eine Warnung. Einzelne Einträge des Pfades werden durch Backslashes (wie beim
Verzeichnis) voneinander getrennt:
Let Drucker$ = @ReadIni$("HKEY_5", \
"System\Current\Controlset\Control\Print\Printer","Default")
Mit WriteIni können INI-Dateien erzeugt und beschrieben werden. In der 32-Bit-Version ist
auch ein Schreiben von Registry-Einträgen möglich.
@RGB(R,G,B)
R,G,B : Wert - Farbwerte (0 .. 31 / 0 .. 255 im TrueColor-Modus)
Ergebnis : Wert (0 .. 32767 / 0 .. 64 Mio im TrueColor-Modus)
Seite 241
RGH-PROFAN²
Die Funktion errechnet eine der 32767 (64 Millionen im TrueColor-Modus) in Profan
möglichen Farben aus den Farbanteilen Rot, Grün und Blau:
@RGB(0,0,0) = 0 (Schwarz)
@RGB(31,31,31) = 32767 (Weiß)
@Rnd(N)
N : Wert
Ergebnis: Integer bzw. LongInt
Zufallszahl zwischen 0 und N-1.
@Right$(S,N)
S : String
N : Anzahl Zeichen
Ergebnis : String
Die N rechten Zeichen des Strings werden zurückgegeben.
@Round(N1,N2)
N1: Float - Wert
N2: Integer - Anzahl der Nachkommastellen
Ergebnis: Float - Gerundeter Wert
Die Zahl N1 wird auf N2 Stellen nach dem Komma gerundet. Da N2 auch negativ sein darf,
kann auch auf volle 100er, 1000er etc. gerundet werden. Bei vollen Tausendern hätte N2
den Wert -3. Der zu rundende Wert N1 darf natürlich auch ein Integer oder LongInt sein!
@SaveFile$(S1,S2)
S1 : String - Überschrift
S2 : String - Namensvorschlag
Ergebnis: Dateiname (incl. Pfad)
Es wird eine Dateiauswahlbox zum Speichern mit der Überschrift S1 geöffnet. Der
Dateiname und/oder Pfad kann geändert werden. Das Ergebnis ist der Name (mit Pfad) unter
dem gespeichert werden kann.
@ScanKey(N)
N : Integer - Scancode
Ergebnis: Integer (1 oder 0)
Wenn der letzte Scancode (virtueller Tastencode) mit N (0 bis 254) übereinstimmt, ist das
Ergebnis 1, anderenfalls ist es 0. Tabelle der Scancodes siehe unter %SCANKEY.
Seite 242
RGH-PROFAN²
@SelectString(N1,N2,S)
N1: Integer - Handle der Listbox
N2: Integer - Start der Suche -1
S: String - Suchbegriff bzw. Anfang des Begriffes
Ergebnis: Integer - Position des Suchbegriffes
In der Listbox N1 wird die erste Zeile angewählt, die mit dem String S beginnt. Die Suche
beginnt dabei nach Zeile N2. Soll die Suche am Anfang der Listbox beginnen, muß N2 der
Wert -1 bekommen. Wird der Eintrag gefunden, dann wird der Auswahlbalken darauf gesetzt
und die Liste nötigenfalls gescrollt, damit der gefundene Eintrag sichtbar wird.
Seite 243
RGH-PROFAN²
@SendKey(N1,N2)
N1 : Integer - Handle des Fensterobjektes
N2 : Integer - virtueller Tastaturcode (Scancode)
Ergebnis : Integer
An das Fenster/das Fensterobjekt mit dem Handle N1 wird ein simulierter Tastendruck
gesandt, wobei N2 der virtuelle Tastaturcode ist:
8913 16 17 20 27 32 33 34 35 36 37 38 39 40 45 46 48 ... 57 65 ... 90 112 ... 135 -
BackSpace
Tab-Taste
Return
Shift
Strg
CapsLock
Esc
Space
BildHoch
BildRunter
Ende
Pos1
Links
Hoch
Rechts
Runter
Einfg
Entf
Taste 0
...
Taste 9
Taste A
...
Taste Z
F1
...
F24
HINWEIS: Diese Funktionen können unter Windows 3.x und Windows 95 unterschiedlich
reagieren; insbesondere dann, wenn aus einer 32-Bit-Anwendung Tastencodes an eine 16Bit-Anwendung gesandt werden und umgekehrt.
Seite 244
RGH-PROFAN²
@SendMessage(N1,N2,N3,N4)
N1 : Integer - Handle des Empfängers
N2 : Integer - Nummer der Meldung
N3 : 16-Bit-Version: Integer - 16-Bit meldungsabhängige Informationen
32-Bit-Version: LongInt - 32-Bit melfungsabhängige Informationen
N4 : LomgInt oder Bereich - 32-Bit meldungsabhängige Informationen
Ergebnis : Integer - Rückgabewert der Meldung
Es wird eine Meldung an das Fenster bzw. Fensterobjekt mit dem Handle N1 gesandt. N2
bezeichnet die Meldung. Die Werte N3 und N4 sind von der gewählten Meldung abhängig.
ACHTUNG: Meldungen die in N4 Zeiger auf Strings oder Datenstrukturen erwarten und/oder
zurückliefern, sollten nur von erfahrenen PROFAN-Programmieren verwandt werden, da
diese zum Absturz von Windows führen können. Auf jeden Fall ist darauf zu achten, daß die
entsprechende Bereichsvariable ausreichend DIMensioniert ist! Die für den PROFAN²Programmierer wichtigsten Messages finden Sie im 4. Kapitel dieser Referenz und eine Liste
mit den Nummern der Meldungen findet sich im Anhang.
@SendString(N,S)
N : Integer - Handle des Fensterobjektes
S : Integer - String
Ergebnis : Integer
An das Fenster/das Fensterobjekt mit dem Handle N wird wird eine Reihe simulierter
Tastendrücke gesandt, wobei S eine beliebige Zeichenkette ist. Sonderzeichen, Umlaute,
Groß- und Kleinschreibung werden entsprechend umgesetzt. Jede Taste wird durch ein oder
mehrere Zeichen repräsentiert. Um normale Buchstaben, Zeichen und Ziffern darzustellen,
geben Sie diese als Zeichenkette an:
@SendString(W%,"Dies ist ein Test!")
Das Plus-Zeichen (+), Caret-Zeichen (^), Prozent-Zeichen (%), die Tilde (~) und Klammern ()
haben bei der SendString-Funktion spezielle Bedeutungen. Um eines dieser Zeichen
anzugeben, schließen Sie das Zeichen in geschweifte Klammern ein. Um beispielsweise das
Plus-Zeichen anzugeben, geben Sie {+} ein:
@SendString(W%,"A {+} B = C")
Um geschweifte Klammerzeichen zu senden, geben Sie {{} und {}} ein.
Zur Angabe von Zeichen, die beim Drücken der zugehörigen Taste (z.B. EINGABETASTE
oder TABULATORTASTE) nicht angezeigt werden, sowie von Tasten, die keine Zeichen
darstellen, verwenden Sie den entsprechenden Codetext in geschweiften Klammern:
@SendString(W%,"Das ist die Eingabe! {ENTER}")
Die Codetexte für die Tasten:
Taste
Code
-------------------------------------------BILD-HOCH
{PGUP}
BILD-RUNTER
{PGDN}
DRUCK
{PRTSC}
EINFG
{INSERT}
ENTER
{ENTER}
ENDE
{END}
Seite 245
RGH-PROFAN²
ENTF
ESC
FESTSTELL
HILFE
LÖSCHTASTE
LINKS
HOCH
RECHTS
RUNTER
NUM
POS1
ROLLEN
RÜCKTASTE
TABULATOR
UNTBR
F1
...
F24
{DELETE} oder {DEL}
{ESCAPE} oder {ESC}
{CAPSLOCK}
{HELP}
{CLEAR}
{LEFT}
{UP}
{RIGHT}
{DOWN}
{NUMLOCK}
{HOME}
{SCROLLLOCK}
{BACKSPACE} oder {BS} oder {BKSP}
{TAB}
{BREAK}
{F1}
...
{F24}
Um Tastenkombinationen anzugeben, die die UMSCHALTTASTE, die STRG-TASTE oder
die ALT-TASTE enthalten, fügen Sie vor dem regulären Tastencode einen bzw. mehrere der
folgenden Codes hinzu: + = UMSCHALTTASTE, ^ = STRG-TASTE und % = ALT-TASTE.
Um eine Tastenkombination anzugeben, bei der eine oder mehrerer dieser Tasten gedrückt
gehalten werden, während gleichzeitig mehrere andere Tasten gedrückt werden, schließen
Sie den Code der Tasten in Klammern ein. Um beispielsweise die UMSCHALTTASTE
gedrückt zu halten, während e und c gedrückt werden, verwenden Sie "+(ec)" (="EC"). Um
die UMSCHALTTASTE gedrückt zu halten, während e gedrückt wird und das auf e folgende
c ohne UMSCHALTTASTE gedrückt wird, verwenden Sie "+ec" (="Ec").
Um eine sich mehrmals wiederholende Taste anzugeben, verwenden Sie die Form Taste
Anzahl, wobei Sie zwischen den Parametern Taste und Anzahl ein Leerzeichen einfügen
müssen. Beispielsweise bedeutet LEFT 42, daß die NACH-LINKS-TASTE 42 Mal gedrückt
wird; h 10 bedeutet, daß der Buchstabe h 10 Mal gedrückt wird.
Zusätzlich können \a, \t und \n verwandt werden. (Zeichen, die nur mit ALTGR erreicht
werden, werden bei der 16-Bit-Version leider nicht gesandt.)
Wenn N den Wert 0 hat, wird an das Fensterobjekt mit dem Focus gesandt; 0 ist
gleichbedeutend mit %GETFOCUS.
HINWEIS: Diese Funktionen können unter Windows 3.x und Windows 95 unterschiedlich
reagieren; insbesondere dann, wenn aus einer 32-Bit-Anwendung Tastencodes an eine 16Bit-Anwendung gesandt werden und umgekehrt.
Seite 246
RGH-PROFAN²
@SetActiveWindow(N)
N : Integer - FensterHandle
Ergebnis : Integer - Handle des vorher aktiven Fensters.
Das Fenster mit dem Handle N wird zum aktiven Fenster.
Siehe auch: %GetFocus, @GetFocus, @SetFocus
@SetBit(N1,N2,N3)
N1 : Integervariable (Integer/LongInt) - Wert
N2 : Bitnummer (0 .. 15)
N3 : Neuer Wert des Bits (0 oder 1)
Ergebnis : LongInt
Die Funktion setzt Bit Nr. N2 in Wert N1 auf N3. Es können also gezielt Bits gesetzt und
zurückgesetzt werden. Beispiel:
declare a%
cls
let a% = 5
print "a%: ";a%
let a% = setbit (a%,5,1)
print "a%: ";a%
let a% = setbit (a%,5,0)
print "a%: ";a%
waitinput
@SetCom(S)
S: String - entsprechend dem Format des DOS-Befehles MODE
Ergebnis: Integer - 0 = OK, <0 = Fehler
Die Schnittstelle wird auf neue Werte eingestellt und die Puffer initialisiert. Die Schnittstelle
muß zuvor mit @OPENCOM geöffnet worden sein. Der String S gibt die Einstellungen im
Format des MODE-Befehles an:
COMx:B,D,P,S
COMx: Die Schnittstelle, z.B. COM2
B: Baud - Geschwindigkeit: 110, 150, 300, 600, 1200,
2400, 4800, 9600 oder 19200
P: Parity: O (Odd), E (Even), M (Mark), S (Space) oder N (None)
D: Datenbits: 6, 7 oder 8
S: Stopbits: 1, 1.5 oder 2
Beispiel:
Let E% = @SetCom("COM2:9600,N,8,1")
Nähere Hinweise siehe im DOS-Handbuch. Wenn diese Einstellungsmöglichkeiten nicht
ausreichen, bietet @SETCOMEXT noch weitere Möglichkeiten. @SETCOMEXT muß nach
@SETCOM aufgerufen werden!
Seite 247
RGH-PROFAN²
Seite 248
RGH-PROFAN²
@SetComExt(N1,N2.N3.N4.N5.N6.N7)
N1: Integer - Handle der Schnittstelle
N2: Integer - RlsTimeOut in ms
N3: Integer - CtsTimeOut in ms
N4: Integer - DsrTimeOut in ms
N5: Integer - Flags:
$0001 = Binärmodus (DCB.fBinary)
$0002 = RTS nicht prüfen
$0004 = Paritätsprüfung ein
$0008 = CTS-Handshake bei Ausgabe
$0010 = DSR-Handshake bei Ausgabe
$0080 = DTR nicht prüfen
$0100 = XON/XOFF bei Ausgabe ein
$0200 = XON/XOFF bei Eingabe ein
$0400 = Paritätsfehlerersatz ein
$0800 = Null entfernen ein
$1000 = Rx Zeichenereignis ein
$2000 = DTR-Handshake bei Eingabe
$4000 = RTS-Handshake bei Eingabe
N6: Integer - Minimalzahl von Zeichen in der Empfangsschlange,
bevor Xon gesendet wird
N7: Integer - Maximalzahl von Zeichen in der Empfangsschlange,
bevor Xoff gesendet wird
Diese Funktion ist erwas für fortgeschrittene Programmierer, sie sich mit den Gegebenheiten
der COM-Schnittstelle gut auskennen. Sie ist nach @SETCOM aufzurufen und erweitert dort
gewählten Einstellungen. Dabei werden die Puffer initialisiert.
Kombinationen der Flags werden durch Addition erzielt. Die angegebenen Werte sind HexWerte! Werte, die nicht verändert werden sollen, sind mit -1 zu belegen. Auf diese Weise
kann mit der Funktion jeder einzelne Parameter der Schnittstelle gezielt geändert werden.
HINWEIS: UNter Windows 95 sind in der 32-Bit-Version von PROFAN² die 3 TimeOutParameter ohne Bedeutung.
Siehe auch: @OpenCom, @SetCom, @ComError
@SetFocus(N)
N : Integer - Handle des Fensterobjektes
Ergebnis : Integer - Handle des vorherigen Fensterobjektes.
Setzt den Focus auf das Fensterobjekt mit dem Handle N. Der Rückgabewert ist der Focus
des des Fensterobjekts, das ihn vorher hatte. Der Focus ist quasi der Kursor unter Windows.
Wenn ein z.B. Eingabefeld den Focus bekommt, erscheint dort der blinkende senkrechte
Strich, die Schreibmarke, und es kann dort etwas eingegeben
werden.
Siehe auch: @SetActiveWindow, @GetFocus, %GetFocus
Seite 249
RGH-PROFAN²
@ShortName$(S)
S: String - langer Dateiname einer Datei (incl. Pfad)
Ergebnis: kurzer Name von Pfad und Datei
Diese Funktion ermittelt den kurzen Dateinamen (System 8.3) zu einem langen Dateinamen.
Dabei darf der Dateiname auch einen Pfad enthalten. Die Funktion ist dann sinnvoll, wenn
Programme oder Funktionen aufgerufen werden sollen, die noch nicht für Windows 95
angepaßt sind und mit langen Dateinamen nichts anfangen können. Das gilt z.B. auch für die
Dateinamen von Datenbanktabellen und Indextabellen in der 16-Bit-Version von PROFAN².
Wenn die Datei nicht existiert wird ein Leerstring zurückgegeben. (Unter Windows 3.x, bzw.
wenn die langen Dateinamen mit SetLFN 0 ausgeschaltet sind, wird immer der String S
zurückgegeben.)
@ShowWindow(N1,N2)
N1 : Integer - Fenster-Handle
N2 : Integer - Abbildungsmodus (1 .. 9)
Das Fenster mit dem Handle N1 wird im Modus N2 angezeigt. Das Ergebnis ist 1 wenn das
Fenster vorher sichtbar war oder 0, wenn es vorher versteckt (unsichtbar) war.
0
1
2
3
4
5
6
7
8
9
- verbirgt und deaktiviert das Fenster
- aktiviert das Fenster und zeigt es in seiner ursprünglichen Größe
- aktiviert das Fenster und verkleinert es zum Symbol
- aktiviert das Fenster und zeigt es größtmöglich an
- zeigt das Fenster in seiner normalen Größe. Das gegenwärtig aktive Fenster
bleibt aktiv.
- aktiviert das Fenster und zeigt es in aktueller Größe
- deaktiviert das Fenster und verkleinert es zum Symbol
- verkleinert das Fenster zum Symbol. Das gegenwärtig aktive Fenster bleibt
aktiv.
- Zeigt as Fenster im aktuellen Zustand. Das gegenwärtig aktive Fenster bleibt
aktiv.
- gleiche Wirkung wie Modus 1
@ScanKey(N)
N : Integer - Scancode
Ergebnis: Integer (1 oder 0)
Wenn der letzte Scancode (virtueller Tastencode) mit N (0 bis 254) übereinstimmt, ist das
Ergebnis 1, anderenfalls ist es 0. Tabelle der Scancodes siehe unter %SCANKEY.
@Sin(N)
N : Wert (Winkel in Bogenmaß)
Ergebnis : Float
Der Sinus des Winkels N.
Seite 250
RGH-PROFAN²
@Space$(N)
N : Anzahl Zeichen
Ergebnis : String
Es wird ein String aus N Leerzeichen zurückgegeben
@SQLInit S
S - String: Initialisierungsstring
Ergebnis: Integer
Die Funktion verbindet das Programm mit dem Datenbankserver.
S ist der Initialisierungsstring, um den Datenbankserver zu öffnen und zu initialisieren. Ist
auf Ihrem System ODBC nicht installiert, kommt die Fehlermeldung "ODBC.DLL nicht
gefunden". Geben Sie als S einen Leerstring an, wird bei den meisten ODBC-Treibern eine
Dialogbox geöffnet, mit der Sie den Datenbankserver wählen können.
Es gibt auch ODBC-Treiber für dBase-, Fox-Pro-, Paradox- und Access-Datenbanken. Ein
solcher Treiber wird z.B. mit WORD 6.0 installiert. Damit ist es möglich auch ohne Netzwerk
ODBC und SQL zu nutzen. Konnte der Datenbankserver nicht geöffnet werden, liefert die
Funktion 0 zurück, ansonsten 1.
Beispiele:
@SQLINIT("DSN=SQLserver;UID=USER;DATABASE=TEST")
@SQLINIT("DSN=dBase-Dateien")
@SQLINIT("")
Die genaue Syntax des Initialisierungsstrings entnehmen Sie bitte der Dokumentation zum
jeweiligen ODBC-Treiber.
@Sqr(N)
N : Wert
Ergebnis : Float
Das Quadrat von N (N²).
@Sqrt(N)
N : Wert
Ergebnis : Float
Die Quadratwurzel zu N.
@String$(V,A)
V: Bereichsvariable
A: Integer - Adresse
Seite 251
RGH-PROFAN²
Ergenis: String - Zeichenkette ab Adresse
Diese Funktion ermittelt eine Zeichenkette ab Adresse (Offset) A in der Bereichsvariablen V.
Dem String werden alle Zeichen ab A hinzugefügt bis entwerde ein Zeichen mit dem Code 0
vorkommt oder die maximale Stringlänge von 255 erreicht ist. Ist A außerhalb des mit DIM
eingestellten Bereiches von V, erfolgt eine Fehlermeldung.
Seite 252
RGH-PROFAN²
@Str$(S)
N : Wert
S : String
Der Wert von N wird in einen String ohne folgende Leerzeichen umgewandelt. Die Länge des
Strings und (bei Float) die Anzahl der Nachkommastellen werden durch die Befehle
NUMWIDTH und DECIMALS eingestellt.
@Sub(N1,N2)
N1 : Wert
N2 : Wert
Ergebnis: Wert
N2 wird von N1 abgezogen (subtrahiert).
@SubStr$(S1,N,S2)
S1 - String: Der zu bearbeitende String
N - Integer: Nummer des Teilstrings
S2 - String: Trennzeichen
Ergebnis: Substring aus S1
Aus dem String S1 wird der N-te Teilstring herausgefiltert,
zwischen den Teilstrings ist. Beispiel:
wobei S2 das Trennzeichen
LET A$ = "eins,zwei,drei,vier,fünf"
PRINT @SUBSTR$(A$,3,",")
Das Ergebnis wäre der String "drei". Wird das Trennzeichen im String S1 nicht gefunden, ist
das Ergebnis für den ersten Teilstring der gesamte String und für alle weiteren der
Leerstring. Ist N kleiner als 1, erfolgt eine Fehlermeldung. Ist N hingegen größer als die
Anzahl der vorhandenen Teilstrings, so ist das Ergebnis ein Leerstring.
HINWEIS: S2 darf auch aus mehreren Zeichen bestehen!
Seite 253
RGH-PROFAN²
@Tan(N)
N : Wert (Winkel in Bogenmaß)
Ergebnis : Float
Der Tangens des Winkels N.
@TestBit(N1,N2)
N1 : Integervariable (Integer/LongInt) - Wert
N2 : Bitnummer (0 .. 15)
N3 : Neuer Wert des Bits (0 oder 1)
Ergebnis : LongInt
Es wird geprüft ob in N1 das Bit Nr. N2 gesetzt ist. Das Ergenis ist der Wert des
entsprechenden Bits.
@Time$(N)
N : Integer (0 .. 1) - Unterfunktion
Ergebnis: String
Die Funktion ermittelt die aktuelle Uhrzeit:
N = 0 : Sunden und Minuten (z.B. "23:45")
N = 1 : Sekunden und 100stel Sekunden (z.B. "39.67")
@TMouse(X1,Y1 - X2,Y2)
X1,Y1 : Integer - links oben
X2,Y2 : Integer - rechts unten
Ergebnis: Integer (0 oder 1)
War beim letzten Mausklick die Maus innerhalb des Rechteckes, ist das Ergebnis 1. Die
Koordinaten sind Textkoordinaten (wie bei LOCATE oder TBOX).
@Translate$(S1,S2,S3)
S1: String - der zu bearbeitende String
S2: String - Suchtext
S3: String - Ersatztest
Ergebnis: String, in dem S2 durch S3 ersetzt wurde
Alle Vorkommen des Strings S2 werden in S1 durch S3 ersetzt.
@Trim$(S)
S : String
Seite 254
RGH-PROFAN²
Ergebnis: String
Die führenden und endenden Leerzeichen eines Strings werden abgeschnitten.
Seite 255
RGH-PROFAN²
@Upper$(S)
S : String
Ergebnis: String
Der String S wird komplett in Großbuchstaben umgewandelt, wobei die deutschen Umlaute
korrekt berücksichtigt werden.
@UseDLL(S)
S: String - Name der DLL-Datei (evt. mit Pfad)
Ergebnis: Integer - Handle der DLL
Die DLL S wird in den Speicher geladen. Ist sie schon geladen wird der Aufrufzähler um 1
erhöht. Das Ergebnis ist das Instanz-Handle der DLL. Dieses wird für den Zugriff auf die
Resourcen der DLL benötigt. Ist das Ergebnis kleiner als 32, trat ein Fehler auf und die DLL
konnte nicht aufgerufen werden. Zu den Fehlercodes siehe unter @WINEXEC.
NEU ab Version 6.0: Es können nun beliebig viele DLL für PROFAN² im Zugriff sein. Wird
eine neue DLL mit @USEDLL geladen, wird der Aufrufzähler der zuletzt geladenen DLL
nicht mehr um 1 erniedrigt. Um die DLL zu entfernen ist der Befehl FREEDLL zu verwenden:
Declare hDLL%
Let hDLL%=@UseDLL("ICONS.DLL")
DrawExtIcon hDLL%,"MSDOS",20,20
FreeDLL hDLL%
Seite 256
RGH-PROFAN²
@Val(S)
S : String
Ergebnis: Wert
Der String S wird in einen numerischen Wert umgewandelt. Das Ergebnis ist 0, wenn der
String nichtnumerische Zeichen enthält. Eine Fehlermeldung oder Warnung erfolgt in diesem
Falle nicht. Als numerische Zeichen gelten auch Strings in binärer, octaler und
hexadezimaler Schreibweise, etwa "%10001", "&0754" oder "$3FA2":
LET A& = @VAL("%10100011")
@Width(H)
H
: Integer - Handle des Fensters, Dialoges, Dialogelementes
Ergebnis : Integer - Breite des Elementes innerhalb des Rahmens
Oftmals benötigt man zum Zeichnen die Größe des Fensters bzw. Dialoges innerhalb des
Rahmens (so einer vorhanden ist). Diese Fläche wird auch der Client genannt. Bei einem
Fenster schließt diese Fläche Menü und Titelleiste nicht mit ein, sondern es wird nur der Teil
ausgemessen, der auch tatsächlich zum Malen, Schreiben, etc. genutzt werden kann
@WinExec(S,N)
S : String - Programm (mit Pfad), das gestartet wird
N : Integer - Abbildungsmodus (0 .. 9)
Ergebnis : Integer - Handle des gestarteten Programmes
Die Anwendung S wird mit dem Abbildungsmodus N gestartet:
0
1
2
3
4
5
6
7
8
9
- verbirgt und deaktiviert das Fenster
- aktiviert das Fenster und zeigt es in seiner ursprünglichen Größe
- aktiviert das Fenster und verkleinert es zum Symbol
- aktiviert das Fenster und zeigt es größtmöglich an
- zeigt das Fenster in seiner normalen Größe. Das gegenwärtig aktive Fenster
bleibt aktiv.
- aktiviert das Fenster und zeigt es in aktueller Größe
- deaktiviert das Fenster und verkleinert es zum Symbol
- verkleinert das Fenster zum Symbol. Das gegenwärtig aktive Fenster bleibt
aktiv.
- Zeigt as Fenster im aktuellen Zustand. Das gegenwärtig aktive Fenster bleibt
aktiv.
- gleiche Wirkung wie Modus 1
Seite 257
RGH-PROFAN²
Das Ergebnis ist das Instanz-Handle der Anwendung. Das Instanz-Handle wird z.B. benötigt,
um auf die Resourcen einer Anwendung zuzugreifen oder um festzustellen, ob die
Anwendung noch aktiv ist. Ist das Ergebnis kleiner als 32, trat ein Fehler auf und die
Anwendung konnte nicht gestartet werden.
0235810 11 12 14 15 16 19 20 21 -
Zuwenig freier Speicher oder die ausführbare Datei war beschädigt
Datei nicht gefunden.
Pfad nicht gefunden.
Es gab einen Fehler beim gemeinsamen Zugriff bzw. einen Zugriffsfehler im
Netzwerk.
Ungenügender Speicher, um die Anwendung zu starten.
Falsche Windows-Version.
Ungültige .EXE-Datei (Keine Windows-.EXE-Datei oder Fehler im .EXEDarstellungsformat).
Anwendung wurde für anderes Betriebssystem entworfen.
Unbekannter .EXE-Dateityp.
Versuch, im Protected Mode (Standardmodus oder erweiterter 386-Modus) eine
für frühere Windows-Versionen erstellte .EXE-Datei zu laden
Es wurde versucht, eine zweite Instanz einer ausführbaren Datei zu laden, die
mehrfache (nicht Read-Only markierte) Datensegmente enthält.
Es wurde versucht, eine komprimierte ausführbare Datei zu laden. Die Datei muß
dekomprimiert werden, bevor sie geladen werden kann.
Eine der DLLs, die zum Start dieser Anwendung notwendig ist, war fehlerhaft.
Die Anwendung benötigt 32-Bit-Erweiterungen (WIN32S).
Beispiel:
LET X%=@WINEXEC("NOTEPAD.EXE",3)
Wenn kein Pfad angegeben ist, sucht Die Funktion @WinExec das Programm in folgender
Reihenfolge:
1.
2.
3.
4.
5.
6.
Im aktuellen Verzeichnis (@GetDir$("@"))
Im Windows-Verzeichnis (%WinPath)
Im Windows-Systemverzeichnis (%SysPath)
Im Verzeichnis, das das aufrufende Programm enthält (@Par$(0))
In den Verzeichnissen, die in der Environment-Variablen PATH aufgeführt sind
(@GetEnv$("PATH"))
in den Verzeichnissen, die in einem Netzwerk (mit dem Befehl MAP)
aufgeführt sind.
ACHTUNG: Aus Gründen, die nur Microsoft (hoffentlich) kennt, darf der String S nicht länger
als 141 Zeichen sein.
Siehe auch: @GetUsage
Seite 258
RGH-PROFAN²
@WinExecWait(S,N)
S
N
: String - Programm (mit Pfad), das gestartet wird
: Integer - Abbildungsmodus
Ergebnis : Integer - Erfolg: 1 = Ok, 0 = Fehler beim Aufruf
Die Anwendung S wird mit dem Abbildungsmodus N gestartet. Im Gegensatz zu @WinExec
wartet diese Funktion, bis das Programm beendet wurde. Erst danach geht's weiter.
Außerdem wird kein Handle zurüchgeliefert, sondern nur der Erfolg oder Mißerfolg der
Funktion. Beispiel:
@WinExecWait("NOTEPAD.EXE",1)
Wenn kein Pfad angegeben ist, sucht Die Funktion @WinExecWait das Programm in der
oben angegebenen Reihenfolge.
ACHTUNG: Aus Gründen, die nur Microsoft (hoffentlich) kennt, darf der String S nicht länger
als 141 Zeichen sein.
@WriteCom(N,S)
N: Integer - Schnittstellenhandle
S: String - Zu sendender Text
Ergebnis: Integer - gesandte Bytes
Der String S wird an die Schnittstelle gesandt. Das Ergebnis enthält die Anzahl der
tatsächlich gesendeten Zeichen. Ist das negativ, trat ein Fehler auf und der Absolutwert
entspricht die Anzahl der vor dem Fehler gesendeten Zeichen. Der aufgetretene Fehler läßt
sich mit der Funktion @COMERROR
ermitteln. Das sollte nach jedem Aufruf von @WRITECOM geschehen! Die Schnittstelle
muß mit @OPENCOM geöffnet worden sein. N ist das dabei ermittelte Handle.
Siehe auch: @ReadCom, @SetCom, @CloseCom
@Word(V,A)
V: Bereichsvariable
A: Integer - Adresse
Ergebnis: Integer - Wert
Diese Funktion ermittelt der Wert des Datenwortes (2 Byte) an der Adresse (Offset) A in der
Bereichsvariablen V. Ist A außerhalb des mit DIM eingestellten Bereiches von V, erfolgt eine
Fehlermeldung.
Seite 259
RGH-PROFAN²
@XOr(N1,N2)
N1 : Wert
N2 : Wert
Ergebnis: Integer
Exklusive ODER-Funktion: Das Ergerbnis ist ungleich 0, wenn N1 ODER N2 (aber nicht
beide) ungleich 0 sind. Anders ausgedrückt: Es ist nur dann 0, wenn beide Argumente gleich
sind.
ACHTUNG: Beide Argumente werden - wie auch bei @Or und @And - BITweise betrachtet!
Seite 260
RGH-PROFAN²
3. Befehle
Jede Programmzeile beginnt mit einem Befehl, wobei auch Funktionen wie Befehle verwandt
werden können. So darf also auf keinen Fall bei einer Zuweisung das LET weggelassen
werden. Nach dem Befehlswort muß immer mindestens 1 Leerzeichen stehen, ansonsten
wird der Befehl nicht als solcher erkannt.
In jeder Programmzeile darf auch immer nur ein Befehl stehen. Mehrere Befehle in einer
Zeile (wie z.B. in BASIC, PASCAL oder C) sind nicht zulässig. Einige Ausnahme ist der
CASE-Befehl.
Seite 261
RGH-PROFAN²
' ... (Kommentarzeichen)
Kommentarzeichen. Im Gegensatz zu REM kann (sollte) es auch hinter einem Befehl in
einer Zeile stehen:
' Unterprogramm
Let X%=125
'X-Position zuweisen
Add VAR,N
VAR - Variablenname (Integer)
N - Integer
N wird zur Variablen VAR addiert. (Ist schneller und einfacher als die @ADD-Funktion.)
Beispiel:
ADD Punkte%,10
AddFiles [*]S
S : String - Dateimaske
Mit diesem Befehl wird eine Dateiliste der Listbox-Liste hinzugefügt. Beispiel:
ClearList
AddFiles "*.RGH"
@ListBox$("Ergebnis",1)
NUR IN DER 32-BIT-VERSION: Wird vor dem String ein Stern angegeben, werden auch alle
Dateien in
den Unterverzeichnissen hinzugefügt, die der Dateimaske entsprechen.
Beispiele:
ClearList
ChDir "C:\"
AddFiles *"*.WAV"
@ListBox$("Ergebnis",1)
Es werden alle WAV-Dateien auf Laufwerk C: gefunden.
ClearList
ChDir "D:\"
AddFiles *"CTL3D.DLL"
@ListBox$("Ergebnis",1)
Es werden alle Vorkommen der CTL3D.DLL auf Laufwerk D: gefunden.
ACHTUNG: Bei zu tiefer Verschachtelung der Verzeichnisse (z.B. im Netzwerk) kann ein
Stack-Überlauf (Stack-Overflow) erfolgen!
AddFonts
Der Listboxliste wird eine Liste der im System vorhandenen Schriften hinzugefügt.
Beispiel:
ClearList
AddFonts
Seite 262
RGH-PROFAN²
AddString S
S : String
Mit diesem Befehl wird der String der Listbox-Liste hinzugefügt. Beispiel:
ClearList
AddString "Item 1"
AddString "Item 2"
Seite 263
RGH-PROFAN²
AddWindows S
S : String - Fenstertitel-Maske
Fügt der Liste die vorhandenen Fenstertitel zu, die mit S beginnen. Ist S ein Leerstring,
werden alle Fenster, die einen Titel haben, der Liste hinzugefügt. Versteckte
Fenster (Fenster ohne Titel) werden nicht eingelesen.
Der Befehl ist z.B. nützlich zum Programmieren von Taskmanagern.
Append #N
N: Wert - Dateinummer (1 .. 15)
Die Datei #N wird geöffnet, um Daten anzufügen. Tritt ein Fehler auf, ist %IoResult größer
als 0. Beispiel:
Assign #1,"TEST.DAT"
Append #1
Case %IoResult:MessageBox "Fehler:",\
"Kann Datei nicht öffnen!",16
Print #1,"Testdaten",56,Hugo$
Close #1
AppendMenu N,S
N : Wert - Menünummer (1 .. 32766)
S : String - Eintrag
Dem PopUp-Menü wird der Eintrag S unter der Nummer N hinzugefügt. Ein vorangestelltes
& sorgt für eine Unterstreichung. Ein Menüeintrag mit der Nummer 254 bleibt wirkungslos,
255 erzeugt immer die PROFAN-Copyright- Meldung. Beispiel:
CreateMenu
AppendMenu 100,"&Laden"
AppendMenu 101,"&Speichern"
AppendMenu 102,"Speichern &als"
TrackMenu 20,130
Case @MenuItem(100):Goto "Laden"
Case @MenuItem(101):Goto "Speichern"
...
Weiteres Beispiel:
PopUp "&Datei"
AppendMenu 100,"&Laden"
AppendMenu 101,"&Speichern"
AppendMenu 102,"Speichern &als"
Separator
SubPopUp "Datei&typ"
AppendMenu 110,"Exe"
AppendMenu 120,"Com"
EndSub
AppendMenu 103,"&Ende"
PopUp .....
Seite 264
RGH-PROFAN²
AppendMenuBar N,S
N : Wert - Menünummer (1 .. 32766)
S : String - Eintrag
Dem Haupt-Menü wird der Eintrag S unter der Nummer N hinzugefügt. Ein vorangestelltes &
sorgt für eine Unterstreichung. Beispiel:
AppendMenuBar 10,"&Laden"
AppendMenuBar 11,"S&peichern"
WaitMouse
Case %MenuItem(10):Goto "Laden"
Arc X1,Y1-X2,Y2; X3,Y3; X4,Y4
X1,Y1 : Wert - Links oben
X2,Y2 : Wert - Rechts unten
X3,Y3 : Start
X4,X5 : Ende
Es wird ein Kreisbogen gezeichnet. X1,Y1 und X2,Y2 bezeichnen das Rechteck, indem der
Kreis sich befindet, die anderen Koordinaten Start und Ende des Kreisbogens.
Assign #N,S
N : Wert - Dateinummer (1 .. 8)
S : String - Dateiname (+ Pfad)
Der Datei Nummer N wird die Datei S zugewiesen. Beispiel:
Assign #1,"DEMO.PRF"
Reset #1
WhileNot @Eof(#1)
Input #1,Zeile$
Print Zeile$
Wend
Close #1
Seite 265
RGH-PROFAN²
Beep
Gibt einen Signalton aus. Zur Tonausgabe siehe auch unter SOUND und PLAY!
BlockWrite #N,B,N1,N2
#N : Dateikennung einer mit OPENRW geöffneten Datei
B : Bereichsvariable
N1 : LongInt - Adresse in der Bereichsvariablen
N2 : LongInt - Anzahl Bytes
In die mit OPENRW geöffneten Datei mit der Kennung #N werden N2 Bytes ab Adresse N1
aus der Bereichsvariablen B geschrieben. Das Beispiel schreibt den Inhalt der
Bereichsvariablen Test# in die Datei TEST.DAT:
Declare Test#
Dim Test#,500
Assign #1,"TEST.DAT"
OpenRW #1
BlockWrite #1,B#,0,500
CloseRW #1
Byte V,A=N
V: Bereichsvariable (muß mit DECLARE deklariert sein)
A: Integer - Adresse in der Bereichsvatiablen
N: Integer - Wert (0 ... 255)
Das Byte an der Adresse (Offset) A im Speicherbereich V wird auf den Wert N gesetzt. Liegt
A außerhalb des mit DIM zugewiesenen Speichers, erfolgt eine Fehlermeldung.
Seite 266
RGH-PROFAN²
Case N:BEF
N : Wert - Bedingungsausdruck
BEF : Profan Befehlszeile
Hat der Ausdruck N einen Wert <> 0, wird BEF ausgeführt, ansonsten geht die
Programmausführung in die nächste Zeile. CASE entspricht einem einzeiligem IF-Befehl.
BEF muß eine komplette Befehlszeile sein; eine Funktion ohne LET-Zuweisung ist nun auch
hier erlaubt. Beispiele:
CASE @Equ$(A$,""):PRINT "A$ ist ein Leerstring"
CASE @Neq(A%,0):Let A$=@ListBox$("Liste",5)
CASE @Neq(A%,0):@ListBox$("Liste",5)
CaseNot N:BEF
N : Wert - Bedingungsausdruck
BEF : Profan Befehlszeile
Hat der Ausdruck N den Wert 0, wird BEF ausgeführt, ansonsten geht die
Programmausführung in die nächste Zeile. CASENOT entspricht einem einzeiligem IFNOTBefehl. Ansonsten gilt das Gleiche, wie für CASE.
Char V,A=S
V: Bereichsvariable
A: Integer - Adresse in der Bereichsvariablen
S: String - Zeichenkette
Der String S wird im Speicherbereich V ab Adresse (Offset) A abgelegt. Das Ende des
Strings wird im Gegensatz zum Befehl STRING nicht mit einem Null-Byte gekennzeichnet.
CharSet N
N: Integer - Zeichenatz
Der für den nächsten USEFONT-Befehl benutzte Zeichensatz wird festgelegt.
0 - ANSI
1 - ASCII
2 - Symbol
Voreinstellung ist ANSI.
Seite 267
RGH-PROFAN²
ChDir S
S : String - Pfadangabe
Es wird zum Verzeichnis S gewechselt. Enthält S eine Laufwerksangabe, so wird auch das
aktuelle Laufwerk gewechselt!
Beispiel:
ChDir "D:\TABELLEN\GRAFIK"
LoadSizedBmp "Umsatz",10,30-400,600;1
CheckMenu N1,N2
N1: Integer - Menüpunkt
N2: Integer - Modus (0, 1)
Der Menüpunkt mit der Menünummer N1 wird mit einem Häkchen versehen, wenn N2
ungleich 0 ist.
Hat N2 den Wert 0 wird ein etwaiges Häkchen entfernt. Beispiel:
PopUp "Anzeige"
AppendMenu 101,"50 %"
AppendMenu 102,"100 %"
CheckMenu 102,1
Der Menüpunkt "100 %" wird mit einem Häkchen versehen.
Chord X1,Y1-X2,Y2; X3,Y3; X4,Y4
X1,Y1 : Wert - Links oben
X2,Y2 : Wert - Rechts unten
X3,Y3 : Start
X4,X5 : Ende
Es wird ein Kreisabschnitt gezeichnet. X1,Y1 und X2,Y2 bezeichnen das Rechteck, indem
der Kreis sich befindet, die anderen Koordinaten Start und Ende des
Kreisabschnittes.
ClearClip
Die Zwischenablage wird gelöscht.
ClearList
Die ListBox-Liste wird gelöscht, d.h. der Zeiger wird auf den Anfang gesetzt. Mit AddFiles,
AddString und/oder AddWindows wird die Liste gefüllt.
Seite 268
RGH-PROFAN²
ClipLoadBmp X,Y;N
X,Y : Position, wo die Bitmap gezeichnet werden soll
N : Integer - Kopiermodus (-1 = transparent)
Mit diesem Befehl kann eine Bitmap (ein Bild) aus der Zwischenablage auf den Bildschirm
gebracht werden. Dabei ist es unerheblich ob die Bitmap von einem anderen PROFAN²Programm, einem anderen Programm oder sonstwie in die Zwischenablage kam.
Der Kopiermodus ist der Gleiche wie bei LoadBmp oder CopyBmp. Beim Kopiermodus -1
(transparent) kennzeichnet der linkeste unterste Pixel der Bitmap die Farbe, die durchsichtig
dargestellt wird.
Close #N
N : Wert - Dateinummer (1 .. 8)
Die mit RESET, APPEND oder REWRITE geöffnete Datei mit der Dateinummer N wird
geschlossen. Beispiel:
Close #Nr%
CloseRW #N
N: Dateikennung (1.. 8)
Eine im Binärmodus geöffnete (OpenRW) Datei wird wieder geschlossen. Hinweis: Wenn
der Befehl auf eine mit RESET, APPEND oder REWRITE geöffnete Datei angwandt wird,
erfolgt ein Fehler (%IOResult wird gesetzt), ebenso im umgekehrten Falle!
Cls [N]
N : Wert - Farbwert (0 .. 32767 bzw. 16 Mio)
Löscht den Bildschirm. Ist noch kein Fenster offen, so wird eins geöffnet. Ab PROFAN² 3.0
kann auch eine Hintergrundfarbe mit angegeben werden. Beispiel:
Cls @RGB(23,23,23)
Diese Zeile würde den Bildschirm löschen und im 32k-Farbmodus ein helles Grau als
Hintergrundfarbe verwenden.
Color C1,C2
C1 : Wert - Textfarbe (0 .. 15)
C2 : Wert - Hintegrund (0 .. 15)
Die Farben des Textmodus (PRINT, TBOX, INPUT) werden festgelegt. Die Farben
entsprechen den 16 Farben von MS-DOS im Textmodus. Beispiel:
Color 15,0
Print "Hugo was here!"
Copy S1 > S2
S1 : String - Quelldatei
Seite 269
RGH-PROFAN²
S2 : String - Zieldatei
Die Quelldatei wird kopiert und erhält Zieldatei als Namen. Beide Strings können auch
Pfadangaben enthalten. Wildcards sind jedoch nicht gestattet. Beispiel:
COPY "C:\START.BAT" > "D:\BAK\START.BAK"
Seite 270
RGH-PROFAN²
CopyBmp X1,Y1-X2,Y2 > X3,Y3;N
X1,Y1 : Wert : Quelle rechts oben
X2,Y2 : Wert : Breite, Höhe
X3,Y3 : Wert : Ziel rechts oben
N : Wert : Kopiermodus (-1 = transparent)
Der Bildschirmausschnitt der beginnend bei X1,Y1 eine Breite von X2 Pixel und eine Höhe
von Y2 Pixel hat, wird an die Position X3,Y3 kopiert. ACHTUNG: X2,Y2 sind keine absoluten
Koordinaten sondern Breite und Höhe des zu kopierenden Bereiches!
Der letzte Parameter bestimmt den Kopiermodus:
-1 01234-
transparent
normales Kopieren
Quelle und Ziel mit UND verknüpft
Quelle und Ziel mit ODER verknüpft
Quelle und Ziel mit XOR verknüpft
Zielbereich invertieren (Quellbereich wird nicht berücksichtigt)
Beim Kopiermodus -1 (transparent) kennzeichnet der linkeste unterste Pixel der Bitmap die
Farbe, die durchsichtig dargestellt wird.
CopyBmpToMem X1,Y1-DX,DY > X2,Y2
X1,Y1 : Wert - linke obere Ecke der zu kopierenden Bitmap
DX,DY : Wert - Größe der zu kopierenden Bitmap
X2,Y2 : Wert - linke obere Ecke der Position im Memorybitmap,
wo die Bitmap gezeichnet werden soll
Der Bildschirmausschnitt, der beginnend bei X1,Y1 eine Breite von DX Pixel und eine Höhe
von DY Pixel hat, wird vom Bildschirm an die Position X2,Y2 iin die Speicherbitmap kopiert.
Die Speicherbitmap kann mit MLoadBMP geladen odere mit MCLS erzeugt worden sein.
WARNUNG: Aus Performancegründen wird nicht überprüft, ob Koordinaten wirklich
innerhalb der Speicherbitmap liegen.
CopySizedBmp X1,Y1-X2,Y2>X3,Y3-X4,Y4;N
X1,Y1 : Wert : Quelle rechts oben
X2,Y2 : Wert : Breite, Höhe
X3,Y3 : Wert : Ziel rechts oben
X4,Y4 : Wert : Breite, Höhe
N : Wert : Kopiermodus (-1 für transparent ist hier nicht erlaubt)
Der Bildschirmausschnitt an X1,Y1 mit der Größe X2,Y2 wird an die Position X3,Y3 in der
Größe X4,Y4 kopiert. ACHTUNG: X2,Y2,X4,Y4 sind keine absoluten Koordinaten, sondern
die Größe!
CreateMenu
Erzeugt ein PopUp-Menü. Das Menü wird mit APPENDMENU gefüllt und mit TRACKMENU
abgefragt. Das Ergebnis steht in der Systemvariablen %MENUITEM.
Seite 271
RGH-PROFAN²
dbCreateIndex S1 > S2
S1 : String - Index-Ausdruck (Feldname)
S2 : String - Index-Name
Es wird ein Index zum Feld S der aktuellen Datenbanktabelle gebildet. Ist keine
Datenbanktabelle geöffnet, erfolgt eine Fehlermeldung.
Das Indexfile erhält den Dateinamen S2. S2 darf keine Dateiendung enthalten, da diese mit
".NDX" (DBase-III-Format) fest vorgegeben ist. S1 darf auch durch "+" verbunden mehrere
Datenbankfelder enthalten, über die der Index gebildet wird. Beispiel:
@dbOpen(#1,"ADRESS.DBF")
@dbUse(#1)
dbCreateIndex "PLZ" > "IXPLZ"
dbCreateIndex "NAME+VORNAME" > "IXNAME"
Im Beispiel wird zunächst die Indexdatei "IXPLZ.NDX" erzeugt, die einen Index auf das Feld
"PLZ" der aktuellen Datenbank-Tabelle enthält. Dann wird die Indexdatei "IXNAME.NDX"
erzeugt, die einen Index auf "NAME" und "VORNAME" enthält. Das erste Sortierkriterium ist
der Name, das zweite der Vorname.
dbCreate S1 > S2
S1 : String - Name der Strukturdatei
S2 : String - Name der erzeugten Tabelle (Bestandsdatei)
Es wird eine Datenbanktabelle ausgehend von der Strukturdatei S1 erzeugt. Die Tabelle
wird unter dem Dateinamen S2 erzeugt. Enthält S2 keine Dateiendung, wird ".DBF"
angehängt. Die Tabelle hat DBase-III-Format. Die Strukturdatei ist eine reine ASCII-Datei,
die die Struktur der Datenbanktabelle beschreibt. Für jedes Feld gibt es eine Zeile, in der
durch Semikolons getrennt die notwendigen Angaben stehen: Feldname, Feldtyp, Feldlänge
und Anzahl der Dezimalstellen.
Beispiel einer Strukturdatei für eine einfache
Adreßverwaltung:
NAME;
VORNAME;
STRASSE;
PLZ_ORT;
TELEFON;
GEBURT;
GEHALT;
C;
C;
C;
C;
C;
D;
N;
30;
30;
30;
30;
20;
8;
10;
0
0
0
0
0
0
2
Zu den Feldtypen siehe unter %DBFTYPE. Die Namen der Felder müssen den DBaseKonventionen entsprechen: Außer Großbuchstaben und Zahlen ist nur der Unterstrich
zugelassen. Der Feldname muß mit einem Buchstaben beginnen. Die maximale
Namenslänge ist 10 Zeichen.
Sowohl Strukturdateien als auch die fertigen Datenbanktabellen können in der PROFAN²Entwicklungsumgebung mit dem Helfer "Datenbankstruktur" erzeugt werden.
Seite 272
RGH-PROFAN²
DDELINK S1,S2
S1: String - Anwendung
S2: String - Thema
Es wird eine DDE-Verbindung zur Anwendung bezüglich des entsprechenden Themas
aufgebaut. Nach erfolgreichem Aufbau enthält die Systemvariable %DDEWIN das Handle
der Anwendung. Kann sich die Anwendung nicht melden, kann es passieren, daß der Befehl
"hängenbleibt": Er wartet auf die Antwort des gerufenen Programmes. Hier hilft ein beliebiger
Tastendruck oder Buttonklick weiter. Wenn es sich nicht gerade um den Programmanager
handelt, ist man auf der sicheren Seite, wenn man die gerufene Anwendung zuvor vermittels
@WINEXEC startet. Sollte die Anwendung nicht verfügbar sein, erhält man hier schon einen
Fehler. Im Falle des Programmanagers sollte jedoch ein Starten desselben unterbleiben, da
mancher Anwender eben eine andere Shell für sein Windows benutzt, die sich jedoch auch
beim Ruf nach dem Programmmanager angesprochen fühlt und entsprechend reagiert. Bei
Erfolg enthält %DDEWin das Handle des gerufenen Programmes, ansonsten 0.
Mit folgendem Befehl weist man den Programmanager (bzw. die aktuelle Shell, so z.B. unter
Windows 95 den Explorer) an, zum Empfang von Befehlen bezüglich des Anlegens von
Gruppen "auf Empfang" zu gehen:
DDELINK "Progman","Progman"
DDEExecute S
S: String - Befehl
Der Befehl S wird an die Anwendung greschickt zu der zuvor mit DDELINK eine Verbindung
aufgebaut wurde. Die möglichen Befehle und die entsprechende Syntax ist der
Dokumentation der Anwendung zu entnehmen. Sollte der DDE-Server nach dem Link
beendet worden sein, kann DDEEXECUTE beim Warten auf eine Antwort "hängenbleiben".
Ein Tastendruk oder Buttonklick hilft hier weiter.
Folgender Befehl erzeugt eine Programmgruppe, zeigt diese und legt in ihr ein Icon an:
IF %DDEWin
let befehl$ = "[CreateGroup(PROFAN-Test,PROFTEST.GRP)]"
let befehl$ = befehl$ ; "[ShowGroup(PROFAN-Test,1)]"
let befehl$ = befehl$ ; "[AddItem(winfile.exe,Datei-Manager)]"
DDEExecute befehl$
ENDIF
DDETerminate
Die aktuelle DDE-Verbindung wird beendet. Jedem DDELink muß (ggf. nach entsprechenden
DDEExecute-Kommandos) ein DDETerminate zur Beendung der Verbindung erfolgen.
Dec VAR
VAR : Variablenname (Integer)
VAR wird um 1 erniedrigt. (Ist identisch mit SUB VAR,1)
Seite 273
RGH-PROFAN²
Decimals N
N: Integer - Stellenzahl
Die Anzahl der auszugebenden Dezimalstellen wird bestimmt. Vorgabewert ist 6. Dieser
Wert wird auch bei der @Str$-Funktion berücksichtigt. (Bei in PROFAN 1.x geschriebenen
Programmen sollte grundsätzlich die Zeile "DECIMALS 0" eingefügt werden, bevor sie unter
PROFAN² 2.x neu compiliert werden.)
Declare VAR [,VAR[,VAR]...]
VAR : Variablen-Name
In PROFAN müssen alle Variablen (zeitlich) vor der ersten Benutzung deklariert werden.
String-Variablen werden durch ein $, LongInt-Variablen durch ein &, Float-Variablen durch
ein ! , Integer-Variablen durch ein % und Bereichsvariablen durch ein # gekennzeichnet.
Beispiel:
Mit Ausnahme der Bereichsvariablen sind alle Variablen, die in Prozeduren oder
Unterprogrammen deklariert werden nur dort lokal gültig. Der verwandte Speicherplatz wird
bei Verlassen des Unterprogrammes/der Prozedur wieder freigegegen.
Decalare XPos%,YPos%,Text$
Def @<Name>(N) <Ausdruck>
<Name> - Funktionsname
N
- Anzahl der Parameter
<Ausdruck>
- Funktion
Eine neue Funktion wird definiert. <Name> ist der Name der neuen Funktion, N
kennzeichnet die Anzahl der übergebenen Parameter und <Ausdruck> beschreibt die neue
Funktion. Die Parameter sind in @$(n), @%(n), @!(n) und @&(n) enthalten.
Declare A%,B%
Def @Max(2) @If(@Gt(@!(1),@!(2)),\
@!(1),@!(2))
Let A%=34
Let B%=12
Print @Max(A%,B%)
Diese Funktion ermittelt den größeren der beiden Werte.
Seite 274
RGH-PROFAN²
Def <Name>(N) *S1,S2,S3,S4
<Name> - Funktionsname
N
- Anzahl der Parameter
S1
- Name der DLL
S2
- Name der Funktion in der DLL
S3
- Parametertypen
S4
- Ergebnistyp
Definiert eine externe Funktion, die in einer 16-Bit-DLL oder der 16-Bit-API vorhanden ist.
Bei den Parametertypen bedeuten:
% = Integer (auch Handles, Words, Bytes und Boolsche Werte sind so zu kennzeichnen)
& = LongInt (auch unsigned Long und alle anderen 4-Byte-Werte)
# = Bereich (hierunter fallen alle Zeiger auf Strings, Datenstrukturen, etc.
Hier können auch Werte zurückgegeben werden, da ja die Adresse des
Speicherbereiches übergeben wird.)
Beim Ergebnistyp bedeutet:
% = Integer (Handles, Words, Bytes, boolsche Werte)
& = LongInt (4-Byte-Werte)
Leerstring (kein Ergebniswert)
Bereichsvariablen dienen dazu, Strings oder Datenstrukturen an die externe Funktion zu
übergeben und/oder von ihr zu bekommen. Natürlich sind sie ausreichend zu
dimensionieren.
Beispiele:
DEF
DEF
DEF
DEF
DEF
DEF
DEF
@MoveWindow(6) *"USER","MoveWindow","%%%%%%",""
@waveOutGetNumDevs(0) *"MMSYSTEM","waveOutGetNumDevs","","%"
@GetWText(3) *"USER","GetWindowText","%#%","&"
@GetApiPixel(3) *"GDI","GetPixel","%%%","&"
@GetSysResources(1) *"USER","GetFreeSystemResources","%","%"
@MsgBox(4) *"USER","MessageBox","%##%","%"
@GetClientRect(2) *"USER","GetClientRect","%#",""
Zwei ausführlich dokumentierte Beispielprogramme finden sich im Verzeichnis BEISPIEL:
DLL- TEST.PRF und RES.PRF. Letzteres ermittelt die freien Systemresourcen und zeigt sie
in einer Messagebox an.
HINWEIS: Auch die 32-Bit-Version von PROFAN² unterstützt den Aufruf von Funktionen in
16-Bit-DLLs. Dazu muß allerdings die Datei "PROF16.EXE" ins Windowsverzeichnis kopiert
werden. Diese dient als Mittler zwischen 32- und 16-Bit-Welt und ist selbst ein 16-BitProgramm.
Seite 275
RGH-PROFAN²
Def <Name>(N) !S1,S2
<Name> - Funktionsname
N
- Anzahl der Parameter
S1
- Name der DLL
S2
- Name der Funktion in der DLL
Definiert eine externe Funktion, die in einer 32-Bit-DLL oder der 32-Bit-API vorhanden ist.
Beispiele:
DEF
DEF
DEF
DEF
DEF
DEF
@MoveWindow(6) !"USER32","MoveWindow"
@waveOutGetNumDevs(0) !"WINMM","waveOutGetNumDevs"
@GetWText(3) !"USER32","GetWindowTextA"
@GetApiPixel(3) !"GDI32","GetPixel"
@MsgBox(4) !"USER32","MessageBoxA"
@GetClientRect(2) !"USER32","GetClientRect"
Dim V,N
V: Bereichsvariable (muß mit DECLARE deklariert sein)
N: 16 Bit-Version: Integer - Größe (1 ... 64500)
32 Bit-Version: LongInt - Größe (abhängig vom Speicher)
Der Bereichsvariablen wird ein Speicherbereich von N Bytes zugewiesen. Solange der
Bereich nicht mit DISPOSE wieder freigeben wird, kann er von keinem anderen Programm
überschrieben oder genutzt werden.
Dim! N
N : Integer - Anzahl 0 .. 32767 bzw. 16380
Festlegung der Größe des Float-Arrays. Der Befehl darf nur einmal im Programm
vorkommen und muß vor dem ersten Gebrauch einer Float-Array-Variablen erfolgen.
Beispiel:
DIM! 56
LIST! 56 = 2345.67
Dim$ N
N : Integer - Anzahl 0 .. 32767 bzw. 16380
Festlegung der Größe des Stringarrays. Der Befehl darf nur einmal im Programm
vorkommen und muß vor dem ersten Gebrauch einer String- Array-Variablen erfolgen.
Seite 276
RGH-PROFAN²
Dim% N
N : Integer - Anzahl 0 .. 32767 bzw. 16380
Festlegung der Größe des Integerarrays. Der Befehl darf nur einmal im Programm
vorkommen und muß vor dem ersten Gebrauch einer Integer- Array-Variablen erfolgen.
Dim& N
N : Integer - Anzahl 0 .. 32767 bzw. 16380
Festlegung der Größe des LongInt-Arrays. Der Befehl darf nur einmal im Programm
vorkommen und muß vor dem ersten Gebrauch einer LongInt- Array-Variablen
erfolgen.
Dispose V
V: Bereichsvariable (muß mit DECLARE deklariert sein)
Der Speicherbereich der Bereichsavariablen V wird wieder freigegeben. Bevor er wieder von
PROFAN² genutzt werden kann, muß er wieder mit einem DIM-Befehl reserviert werden.
WICHTIG: Jeder mit DIM zugewiesener Speicherbereich muß mit DISPOSE wieder
freigeben werden, bevor das PROFAN²- Programm beendet wird. Ansonsten ist der Speicher
für den Rest der Windows-Sitzung blockiert!
DrawExtBmp I,S,X,Y;N
I
: Integer - Instanzhandle der EXE bzw. DLL,
die die Bitmap enthält
S
: String - Name oder Nummer der Bitmap
X,Y : Position, wo die Bitmap gezeichnet werden soll
N
: Integer - Kopiermodus (-1 = transparent)
Mit diesem Befehl kann eine Bitmap (ein Bild) aus einem anderen Programm oder aus einer
DLL benutzt und auf den Bildschirm gebracht werden. Dazu ist es notwendig den Namen
oder die Nummer der Bitmap zu kennen. Bitmap-Resourcen können wahlweise durch einen
Namen oder einen Integer gekennzeichnet sein. Das Instanz-Handle wird bei DLLs mittels
@UseDLL ermittelt und bei EXE-Dateien mittels @WinExec. Das Handle des ausführenden
Programmes ist in der Systemvariablen %HInstance. Es ist also möglich, alle in einem
Programm verwandten Bitmaps mittels eines Tools wie des Resource- Workshops von
Borland in eine DLL zu packen. Ebenso ist es z.B. möglich, die PROFRUN.EXE vor dem
Linken entsprechend zu erweitern.
Der Kopiermodus ist der Gleiche wie bei LoadBmp oder CopyBmp. Beim Kopiermodus -1
(transparent) kennzeichnet der linkeste unterste Pixel der Bitmap die Farbe, die durchsichtig
dargestellt wird.
Seite 277
RGH-PROFAN²
DrawExtIcon N,S,X,Y
N : Integer : Handle der externen Datei
S : String : Icon-Name oder -Nummer
X,Y : Wert : Koordinaten
Das externe Icon S aus dem Modul mit dem Handle N wird an Position X,Y gezeichnet. Bei
einer DLL wird das Handle mit @USEDLL ermittelt, bei einer EXE-Datei mit @WINEXEC.
Auf die Icons einer EXE-Datei kann nur solange zugegriffen werden, solange die EXE-Datei
ausgeführt wird. Beispiel:
Declare hDLL%
Let hDLL%=@UseDLL("ICONS.DLL")
DrawExtIcon hDLL%,"MSDOS",20,20
DrawIcon S,X,Y
S : String : Icon-Name
X,Y : Wert : Koordinaten
Das Icon S wird an Position X,Y gezeichnet. Beispiel:
DrawIcon "Knopf1",12,12
18 Icons sind in PROFAN.EXE enthalten, können aber z.B. mit einem Resourcen-Toolkit
verändert werden.
Die Icons, die in Profan vorhanden sind:
PROFAN KNOPF1 EIS
BAUM KNOPF2 COMPUTER
WEG TEXT GESICHT
EIMER MUELL MUENZE
STEIN WINDOWS WASSER
DOS EDITOR SAND
Es gibt auch Icon-Editoren, mit denen sie verändert werden können.
DrawLibIcon S,N,X,Y
S - String: Name der Icon-Datei (mit Pfad)
N - Integer: Nummer des Icons in der Icon-Datei
X,Y - Integer: Position des Icons
Mit dem Befehl kann ein Icon aus einer beliebigen Icon-Datei verwandt werden. Die Nutzung
von Icons aus EXE- und DLL-Dateien ist ebenso möglich wie die Verwendung einzelner
Icons (*.ICO). Das erste Icon einer Datei hat die Nummer 0. Die Anzahl der Icons in einer
Datei kann mit der Funktion @ICONCOUNT ermittelt werden. Beispiele:
DrawLibIcon "PROGMAN.EXE",2,100,100
DrawLibIcon "SPIEL.ICO",0,200,100
Seite 278
RGH-PROFAN²
DrawSizedExtBmp I,S,X1,Y1-X2,Y2;N
I
: Integer - Instanzhandle der EXE bzw. DLL,
die die Bitmap enthält
S
: String - Name der Bitmap
X1,Y1 : linke obere Ecke der Position, wo die Bitmap
gezeichnet werden soll
X2,Y2 : Größe der Bitmap
N
: Integer - Kopiermodus
Dieser Befehl bewirkt das Gleiche wie DrawExtBmp mit dem Unterschied, daß das Bild beim
Zeichnen verkleinert oder vergrößert werden kann: Mit dem zusätzlichen Paramaterpaar wird
die Größe des zu zeichnenden Bildes angegeben. Der Kopiermodus -1 (transparent) ist hier
nicht zulässig.
DrawSysIcon N,X,Y
N : Wert - Icon-Nummer (0 .. 4)
X,Y : Wert - Koordionaten
Das Windowseigene Icon mit der Nummer N wird an Position X,Y gezeichnet.
0 : Windows-Symbol
1 : STOP-Zeichen
2 : Fragezeichen
3 : Ausrufezeichen
4 : Info-Zeichen
DrawText X,Y,S
X,Y : Wert - Koordinaten
S : String oder numerischer Wert
Der Text S wird an der Bildschirmposition X,Y mit dem durch USEFONT eingestellten Font
in der durch TEXTCOLOR eingestellten Farbe dargestellt.
DrawText 10,50,"Highscore:"
Ab Profan² 2.5 darf S auch ein numerischer Literal oder eine numerische Variable sein. Vor
der Ausgabe wird sie unter Berücksichtigung von Numwidth und Decimals in einen String
umgewandelt:
DrawText 10,50,HighScore&
Seite 279
RGH-PROFAN²
Ellipse X1,Y1-X2,Y2
X1,Y1 : Wert - Links oben
X2,Y2 : Wert - Rechts unten
Es wird ein Kreis, bzw. eine Ellipse gezeichnet. X1,Y1 und X2,Y2 bezeichnen das Rechteck,
indem die Ellipse sich befindet.
EnableMenu N1,N2
N1: Integer - Menüpunkt
N2: Integer - Modus (0, 1, 2)
Der Menüpunkt mit der Menünummer N1 wird deaktiviert, wenn N2 den Wert 1 hat bzw.
deaktiviert und grau gefärbt, wenn N2 den Wert 2 hat. Hat N1 den Wert 0 wird der
Menüpunkt normal dargestellt und ist anwählbar.
EnableWindow N1,N2
N1: Integer - Fensterhandle
N2: Integer - 0 = gesperrt, 1 = normal
Das Fensterobjekt mit dem Handle N1 wird gesperrt bzw. entsperrt. Wenn ein Element
gesperrt (disabled) ist, ist ein Anklicken bzw. eine Eingabe unmöglich.
End
Programmende. Ohne weitere Abfrage wird das Profan-Programm verlassen.
Erase #N S
N : Wert - Dateinummer (1 .. 15)
Die Datei mit dem Dateikennzeichen N wird gelöscht. Beispiel:
ASSIGN #1,"TEST.BAK"
ERASE #1
ExitWindows N
N: Integer - Modus (0, 1)
Mit diesem Befehl wird die Windowssitzung beendet und Windows (nach den üblichen
Sicherheitsabfragen, falls noch Dateien offen sind) verlassen. Hat N den Wert 1 wird
Windows anschließend gleich erneut gestartet. Das kann für Installationsprogramme, die z.B.
die WIN.INI ändern sinnvoll sein.
Seite 280
RGH-PROFAN²
FileMode N
N: Integer - Filemodus (siehe DOS-Dokumentation)
Der Filemodus der für das Öffnen von Dateien (mit RESET, REWRITE oder OPENRW) und
den Zugriff auf diesen gilt, wird eingestellt. Unter allen DOS-Versionen sind folgende
Filemodi vorhanden:
0:
1:
2:
Nur lesen
Nur schreiben
Lesen und Schreiben
Neuere DOS-Versionen kennen noch weitere Modi, die besonders im Netzwerk von Interesse
sind.
Standardmäßig wird bei allen oben genannten Befehlen FileMode 2 benutzt. Will man jedoch
eine Datei lesen, die das Attribut ReadOnly (Nur lesen) hat, so muß vor dem RESET bzw.
OPENRW der FileMode auf 0 gesetzt werden.
Fill X,Y,C
X,Y : Wert - Koordinaten
C : Wert - RGB-Farbwert der Grezfarbe
Ausgehend von Punkt X,Y wird alles bis zu einem Rahmen, der die Farbe C hat, mit dem
aktuellen Pinsel (USEBRUSH) gefüllt. Beispiel:
Fill 20,50,@RGB(0,0,31)
Font N
N : Wert - Font - Nummer (0 .. 2)
Der Font N für den Textmodus (Textausgabe mit PRINT) wird gewählt:
0 : System-Font (ANSI-Zeichensatz)
1 : OEM-Font (ASCII-Zeichensatz)
2 : ANSI-Font
Seit Version 4.5a bestimmt dieser Befehl auch, welchen Zeichensatz PROFAN² in den
dBase-III-Tabellen benutzt! Bei 1 wird der OEM-Zeichensatz gewählt. Dieser ist dann zu
verwenden, wenn etwa von anderen Programmen auf die Daten zugegriffen werden soll.
Diese erwarten bei einer dBase-III-Datei in der Regel den ASCII- bzw. OEM-Zeichensatz;
das gilt auch für die ODBC-Treiber.
FreeDLL H
H : Integer - Handle der DLL
Der Aufrufzähler der DLL mit dem Handle H wird um 1 erniedrigt. Erreicht der Zähler 0, wird
die DLL aus dem Speicher entfernt. Zu jedem @UseDLL innerhalb eines Programmes muß
es ein FreeDLL geben.
Seite 281
RGH-PROFAN²
GetMessage
Dieser Befehl wartet auf die nächste für das Programm bestimmte Message, bestückt die
Systemvariablen %Message, %MWnd, &WParam und &LParam entsprechend und leitet die
Message an Windows weiter.
WICHTIG: In einer While-Schleife kann entweder ein GetMessage ODER ein anderer der
WAIT-Befehle stehen! Die PROFAN²-Systemvariablen, die für gewöhnlich von den WAITBefehlen gesetzt werden (etwa %SCANKEY, %KEY, %MENUITEM, etc.) werden von
GETMESSAGE nicht gesetzt. Hier muß der Programmierer die Messages selbst auswerten!
If N ... [ElseIf N ...] [Else ... ] EndIf
N : Wert . Bedingungsausdruck
Die zwischen IF und ENDIF stehenden Zeilen werden nur dann ausgeführt, wenn N ungleich
0 ist. Beispiel:
If @Equ(Test%,78)
Print "Test% ist 78!"
Print "-------------"
EndIf
Auch eine Abrage auf mehrere Bedingungen (z.B. bei der Auswertung eines Menüs) ist mit
ELSEIF möglich. Sobald eine Bedingung erfüllt ist, wird der zugehörige Programmteil
abgearbeitet und anschließend mit der Zeile nach dem ENDIF fortgefahren:
IF @Lt(A%,1)
COLOR 1,15
PRINT "A ist
ELSEIF @Equ(A%,1)
COLOR 2,15
PRINT "A ist
ELSEIF @Equ(A%,2)
COLOR 3,15
PRINT "A ist
ELSE
PRINT "A ist
ENDIF
kleiner als 1"
gleich 1"
gleich 2"
größer als 2"
ACHTUNG: Hinter ELSEIF muß ein Bedingungsausdruck stehen. Fehlt dieser würde der
Interpreter das ELSEIF zwar wie ELSE behandeln, aber das Runtime-Modul würde den
Fehler merken und mit einer Fehlermeldung "Zu wenig Parameter" abbrechen.
Seite 282
RGH-PROFAN²
IfNot N ... [ElseIf N ... ] [Else ...] EndIf
Als Kurzform für If @Not(N) kann auch das kürzere (und schnellere) IfNot verwandt werden:
IfNot @Equ(Test%,78)
Print "Test% ist nicht 78!"
Print "-------------------"
EndIf
Inc VAR
VAR - Variablenname (Integer)
VAR wird um 1 erhöht. (Ist identisch mit ADD VAR%,1)
Input #N,VAR
N : Wert - Dateikennzeichen (1..8)
VAR : Variable
Aus der Datei #N wird ein Wert in die Variable gelesen. Beispiel:
Assign #1,"TEST.DAT"
Reset #1
Input #1,Titel$
Input #1,Anzahl%
Close #1
Input VAR
VAR : Variable
Von der Tastatur wird ein Wert in die Variable gelesen (Textmodus). Beispiel:
Print
Input
Print
Input
"Geben Sie den Titel ein: ";
Titel$
"Geben Sie die Anzahl ein: ";
Anzahl%
Windowstypischer ist jedoch die Verwendung des Eingabedialoges mit der Funktion
@Input$.
InsertMenu N1,N2,S
N1: Integer - Menüpunkt vor dem eingefügt wird
N2: Integer - Neuer Menüpunkt (0 .. 32766)
S: String - Text des neuen Menüpunktes
Vor dem Menüpunkt mit der Nummer N1 wird ein neuer Menüpunkt mit der Menünummer N2
und dem Menütext S eingefügt. Für Menünummer und -text gilt das gleiche, wie für
APPENDMENU.
Seite 283
RGH-PROFAN²
Let VAR=N|S
VAR : Variablenname
N : Wert
S : String
Einer zuvor mit DECLARE deklarierten Variablen wird ein Wert zugewiesen. Das LET darf
nicht weggelassen werden!
Beim LET-Befehl für Stringvariablen können nun - ähnlich wie beim PRINT-Befehl - mehrere
Stringausdrücke durch Semikolon bzw. Komma getrennt angegeben werden. Werden zwei
Stringausdrücke mit einem Komma getrennt, wird ein Leerzeichen eingefügt. Diese Methode
ist einfacher und deutlich (!) schneller als das Zusammenfügen von Strings mittels der
@ADD$-Funktion. Beispiel:
LET Text$ = "Du hast",@Str$(Score%),"Punkte erzielt!"
HINWEIS: Die automatische Typumwandlung funktioniert bei einfachen Variablen. Bei
Funktionen, die einen numerischen Wert zurückggeben, wird nicht immer automatisch
umgewandelt, daher ist hier immer die Funktion @Str$ zu verwenden!
Line X1,Y1-X2,Y2
X1,Y1 : Wert - Startkoordinaten
X2,Y2 : Wert - Endkoordinaten
Es wird eine Linie zwischen den angegebenen Punkten in der mit USEPEN eingestellten
Linienart und Strichstärke gezeichnet.
LineTo X1,Y1
X1,Y1 : Wert - Endkoordinaten
Es wird eine Linie vom zuletzt gezeichneten (oder mit MOVETO gesetzten) Punkt zum
angegebenen Punkt in der mit USEPEN eingestellten Linienart und Strichstärke
gezeichnet.
ListBoxItem$ N = S
N : Integer - Index (0 .. 9999)
S : String
Der String S wird wird an Position N in die ListBox-Liste übernommen.
List! N1 = N2
N1 : Integer - Index (0 .. 32767 bzw. 16380)
N2 : Float - Wert
Der Wert N2 wird an Position N1 in die Float-Liste übernommen. Beispiel:
List& 1 = 5.67
List& 2 = 1045.324
Print @List!(1),@List!(2)
Seite 284
RGH-PROFAN²
List$ N = S
N : Integer - Index (0 .. 32767 bzw. 16380)
S : String
Der String S wird wird an Position N in die Stringliste übernommen.
List% N1 = N2
N1 : Integer - Index (0 .. 32767 bzw. 16380)
N2 : Integer - Wert
Der Wert N2 wird an Position N1 in die Integerliste übernommen.
List& N1 = N2
N1 : Integer - Index (0 .. 32767 bzw. 16380)
N2 : LongInt - Wert
Der Wert N2 wird an Position N1 in die LongInt-Liste übernommen.
LoadBmp S, X,Y ;N
S : String - Name der Bilddatei
X,Y : Wert - Koordinaten
N : Wert - Kopiermodus (-1 = transparent)
Eine Windows-Bild-Datei (BMP-Format) wird geladen und unter Berücksichtigung des
Kopiermodus angezeigt. Das Bild muß im BMP- oder RLE-Format vorliegen. Es wird an der
Position X,Y in Originalgröße angezeigt. Beispiel:
-1 01234-
transparent
normales Kopieren
Quelle und Ziel mit UND verknüpft
Quelle und Ziel mit ODER verknüpft
Quelle und Ziel mit XOR verknüpft
Zielbereich invertieren (Quellbereich wird nicht berücksichtigt)
S kann auch Pfadangaben enthalten. Das Bild muß im BMP-Format vorliegen. Es wird an
der Position X,Y in Originalgröße angezeigt. Beispiel:
LoadBmp "C:\WINDOWS\PAPER.BMP",10,10;0
Der letzte Parameter bestimmt den Kopiermodus. Beim Kopiermodus -1 (transparent)
kennzeichnet der linkeste unterste Pixel der Bitmap die Farbe, die durchsichtig dargestellt
wird.
LoadSizedBmp S, X1,Y1-X2,Y2;N
S : String - Name der Bilddatei
X1,Y1 : Wert - Koordinaten
X2,Y2 : Wert - Größe
N : Wert - Kopiermodus (-1 ist hier nicht erlaubt)
Seite 285
RGH-PROFAN²
Eine Windows-Bild-Datei (BMP-Format) wird geladen und unter Berücksichtigung des
Kopiermodus angezeigt. Das Bild wird an der Position X1,Y1 in der angegebenen Größe
angezeigt.Durch negative Werte für X2 bzw. Y2 sind auch Spiegelbilder realisierbar.
Locate X,Y
X : Wert - Zeile
Y : Wert - Spalte
Der nächste PRINT- oder INPUT-Befehl positioniert auf Zeile X, Spalte Y. Wirkt nur für
Textmodus-Befehle.
Long V,A=N
V: Bereichsvariable (muß mit DECLARE deklariert sein)
A: LongInt - Adresse in der Bereichsvatiablen
N: LongInt - Wert (0 .. 4,29 Milliarden)
Das Word (32-Bit-Wert = 4 Byte) an der Adresse (Offset) A im Speicherbereich V wird auf
den Wert N gesetzt. Liegt A außerhalb des mit DIM zugewiesenen Speichers, erfolgt eine
Fehlermeldung.
HINWEIS: Da vier Byte geschrieben werden, werden die Adressen A bis A+3 benutzt, wobei
an Adresse A das niedrigstwertige und an Adresse A+3 das höchstwertige Byte geschrieben
wird. Sollen mehere LongInt in den Bereich geschrieben werden, etwa um ein Array zu
simulieren, so ist zwischen den Adressen ein Abstand von 4 einzuhalten. Beispiel:
DECLARE Bereich#
DIM Bereich#,12
LONG Bereich#,0 =231056
LONG Bereich#,4 =510251
LONG Bereich#,8 = 516
PRINT @LONG(Bereich#,0)
PRINT @LONG(Bereich#,4)
PRINT @LONG(Bereich#,8)
DISPOSE Bereich#
Seite 286
RGH-PROFAN²
MCLS DX,DY
DX,DY : Wert - Breite, Höhe
Es wird eine leere Speicher-Bitmap in dere Größe DX, DY angelegt. Mit CopyBmpToMem
oder per Umleitung mit StartPaint -1 kann diese Bitmap bearbeitet werden. Mit MCopyBmp
und MCopySizedBmp können beliebige Teile auf den Bildschirm kopiert werden.
MCopyBmp X1,Y1-X2,Y2 > X3,Y3;N
X1,Y1 : Wert : Quelle rechts oben
X2,Y2 : Wert : Breite, Höhe
X3,Y3 : Wert : Ziel rechts oben
N : Wert : Kopiermodus (-1 = transparent)
Der Bildschirmausschnitt der beginnend bei X1,Y1 eine Breite von X2 Pixel und eine Höhe
von Y2 Pixel hat, wird aus dem mit MLOADBMP geladenem Bild an die Position X3,Y3
kopiert. ACHTUNG: X2,Y2 sind keine absoluten Koordinaten sondern Breite und Höhe! Der
letzte Parameter bestimmt den Kopiermodus:
-1 01234-
transparent
normales Kopieren
Quelle und Ziel mit UND verknüpft
Quelle und Ziel mit ODER verknüpft
Quelle und Ziel mit XOR verknüpft
Zielbereich invertieren (Quellbereich wird nicht berücksichtigt)
Beim Kopiermodus -1 (transparent) kennzeichnet der linkeste unterste Pixel der Bitmap die
Farbe, die durchsichtig dargestellt wird.
MCopySizedBmp X1,Y1-X2,Y2 > X3,Y3-X4,Y4;N
X1,Y1 : Wert - linke obere Ecke der zu kopierenden Bitrmap
X2,Y2 : Wert - Größe der zu kopierenden Bitmap
X3,Y3 : Wert - linke obere Ecke der Position, wo die Bitmap
gezeichnet werden soll
X4,Y4 : Wert - Größe der Bitmap
N : Wert - Integer - Kopiermodus (-1 ist hier nicht erlaubt)
Der Bildschirmausschnitt der beginnend bei X1,Y1 eine Breite von X2 Pixel und eine Höhe
von Y2 Pixel hat, wird aus dem mit MLOADBMP geladenem Bild an die Position X3,Y3 X4,Y4 kopiert. ACHTUNG: X2,Y2 und X4,Y4 sind keine absoluten Koordinaten sondern
Breite und Höhe! Der letzte Parameter bestimmt den Kopiermodus.
MLoadBMP S
S : String - Dateiname der Bilddatei (evtl. mit Pfad)
Die Bilddatei S wird in den Speicher geladen, aber nicht angezeigt. Mit MCOPYBMP können
Teile des Bildes (oder auch die ganze Bild) auf den Bildschirm kopiert werden. HINWEIS: Es
kann immer nur eine Bilddatei im Speicher sein. Bei jedem Aufruf von MLOADBMP wird die
vorher geladene Bilddatei überschrieben.
MkDir S
Seite 287
RGH-PROFAN²
S : String - Pfadangabe
Das Verzeichnis S wird angelegt. Im Falle eines Fehlers hat %IORESULT einen von 0
verschiedenen Wert. Beispiel:
MkDir "C:\WINDOWS\TEST"
Siehe auch: ChDir, RmDir
Seite 288
RGH-PROFAN²
MoveTo X1,Y1
X1,Y2 : Wert - Koordinaten
Der Grafik-Kursor wird zum angegebenen Punkt bewegt, ohne eine Linie zu zeichnen.
Praktisch ist dieser Befehl nur im Zusammenhang mit nachfolgendem LINETO-Befehl
sinnvoll.
Music S
S: String (Noten)
Der Parameter S ist ein String in einer eigenen Makrosprache. Diese Makrosprache ist
kompatibel zur Music-Makro-Sprache, wie sie von BASIC her (für den PLAY-Befehl)
bekannt ist:
A..G
On
>
<
Ln
Pn
Tn
MN
ML
MS
entsprechende Note:
#
- Erhöhung
+
- Erhöhung
- Erniedrigung
.
- Punktiert
n
- kennzeichnet die Notenlänge. 4 steht für Viertel, 2 für Halbe, etc.
Wird n weggelassen, wird die Standardlänge verwandt.
Oktave n (0..6) wird gewählt
Eine Oktave höher
Eine Oktave niedriger
Setzt die Standardlänge
Pause in der Länge n.
Tempo: Anzahl der Viertelnoten pro Minute. Defaultwert ist 120.
normale Musik. Jede Note wird 7/8 der Zeit gespielt
Legato. Die Töne gehen in einander über.
Staccato. Jede Note wird nur 3/4 der Zeit gespielt.
Um eine Tonleiter in Viertel-Noten in der 3. Oktave zu spielen, reicht folgender Befehl:
MUSIC "O3 C4 D4 E4 F4 G4 A4 B4 > C4"
Erhöhungs- und Erniedrigungszeichen sind genauso möglich, wie auch Punktierungen:
MUSIC "C#2 F-8 G4."
Pausen haben den Notenwert "P".
Für Soundkartebesitzer wurde die Makrosprache erweitert: Der Befehl MUSIC gibt nun bei
vorhandenem MIDI-Gerät (Soundkarte oder MIDI-Schnittstelle) die Musik über das MIDIGerät aus. Die Musik-Makro-Sprache von PROFAN² wurde dazu um folgende Befehle
erweitert:
In
Kn
Vn
Instrument n (0 ... 127) wird auf den aktuellen Kanal gelegt.
Kanal n (0..15) wird wiedergegeben.
Der aktuelle Kanal wird auf Lautstärke n (0...127) eingestellt.
Voreingestellt ist Kanal 0 mit Instrument 0 (= Klavier) in der Laustärke 100. Diese
Erweiterungen wirken nur dann, wenn das MIDI-Gerät korrekt installiert ist, ansonsten erfolgt
die Ausgabe in der 16-Bit-Version über den Lautsprecher und in der 32-Bit-Version überhaupt
nicht.
Seite 289
RGH-PROFAN²
NextPage
Mit NEXTPAGE wird innerhalb des Druckauftrages zwischen STARTPRINT und ENDPRINT
eine neue Seite begonnen.
NumWidth N
N: Integer - Mindestweite
Mindestweite der Ausgabe numerischer Werte. Dieser Wert wird auch von der @STR$Funktion und dem Befehl DrawText verwandt. Ist der Ausgabestring kürzer wird er mit
führenden Leerzeichen aufgefüllt. Standarteinstellung ist 0.
Siehe auch: Decimals
Seite 290
RGH-PROFAN²
OpenRW #N
#N: Dateikennung (1 - 8)
Die Datei mit der Kennung #N wird im Binärmodus zum Lesen und Schreiben geöffnet. Es
können beliebige Bytes aus der Datei gelesen (@GetByte) und beliebige Bytes in die Datei
geschrieben (PutByte) werden. Mit @FilePos kann die Position des Dateizeigers ermittelt
werden und mit SEEK wird sie verändert.
Orientation N
N : Integer - Winkel (in Zehntel-Grad!)
Bestimmt den Winkel der Textausgabe; wird durch den nächsten USEFONT- Befehl
aktiviert. (Sinnvoll nur bei TRUE-Type-Fonsts.) Beliebige Textausrichtungen auf dem
Bildschirm und Drucker sind somit möglich!
OpenRW #N
N: Dateikennung (1 - 15)
Die Datei mit der Kennung #N wird im Binärmodus zum Lesen und Schreiben geöffnet. Es
können beliebige Bytes aus der Datei gelesen (@GetByte) und beliebige Bytes in die Datei
geschrieben (PutByte) werden. Mit @FilePos kann die Position des Dateizeigers ermittelt
werden und mit SEEK wird sie verändert.
Siehe auch: Rewrite, Append und Reset.
OutP N1,N2
N1 : Integer - Port-Adresse
N2 : Integer - Auszugebender Wert
An Port N1 (und N1+1) wird der Wert N2 ausgegeben, wobei N2 als ein Datenwort (=2 Byte
bzw. 16 Bit) interpretiert wird. Das niederwertige Byte wird an Port N1 ausgegeben und das
höherwertige Byte an Port N1+1. Um ein Byte auszugeben, ist OUTPB zu verwenden.
Mit der Funktion @INP kann ein Datenwort am Port gelesen werden.
OutPB N1,N2
N1 : Integer - Port-Adresse
N2 : Integer - Auszugebender Wert (0 ... 255)
An Port N1 wird der Wert N2 ausgegeben, wobei N2 als ein Byte interpretiert wird. Mit der
Funktion @INPB kann ein Byte am Port gelesen werden.
ACHTUNG: Die beiden OUT-Befehle sollte man nur verwenden, wenn man genau weiß,
was man macht. Sinn machen die Befehle vor allem dann, wenn man eine I/O-Karte, deren
Adressen man kennt, mit einem Programm ansprechen will. Falsche Werte können
Windows zum Absturz bringen oder z.B. im Falle der Register der Grafikkarte den Monitor in
Mitleidenschaft ziehen.
Ein Ausprobieren ohne Plan kann Ihre Hardware beschädigen und zu Datenverlust führen!
Seite 291
RGH-PROFAN²
Parameters VAR [,VAR[,VAR] ...]
VAR - Variablennamen
Die Aufrufparameter einer Prozedur werden Variablen zugewiesen, die innerhalb der
Prozedur bekannt sind. Ein Beispiel findet sich unter PROC. Die Anzahl der Variablen sollte
gleich der Anzahl der Übergabeparameter sein; überprüft wird dieses aber ebensowenig, wie
die Datentypen. Gegebenenfalls erfolgt eine automatische Umwandlung.
Siehe auch: Proc
PassWord S
S: String - Paßwort
Dieser Befehl setzt das Paßwort, daß für die Funktion @PWD$ zum Ver- und Entschlüsseln
von Strings verwandt wird. WICHTIG: Das Entschlüsseln funktioniert nur dann korrekt, wenn
das gleiche Paßwort wie beim Verschlüsseln benötigt wird. Soll die Verschlüsselungsfunktion
ausgeschaltet werden, ist der Befehl mit einem Leerstring zu benutzen:
PASSWORD ""
HINWEIS: Diese Verschlüsselung erschwer zwar den Zugriff auf die Daten, ist aber (noch)
nicht unknackbar! Dafür bleibt die Sortierreihenfolge der Daten weitgehend erhalten.
Pie X1,Y1-X2,Y2; X3,Y3; X4,Y4
X1,Y1 : Wert - Links oben
X2,Y2 : Wert - Rechts unten
X3,Y3 : Start
X4,X5 : Ende
Es wird ein Kreisteil (Tortenstück) gezeichnet. X1,Y1 und X2,Y2 bezeichnen das Rechteck,
indem der Kreis sich befindet, die anderen Koordinaten Start und Ende des Kreisteiles.
Play N1,N2,N3
N1 : Wert - Notenwert (0 = Pause)
N2 : Wert - Dauer
N3 : Wert - Punkte
Die Notenwerte werden in Halbtonschritten hochgezählt. Die Dauer wird reziprok angegeben:
4 bedeutet z.B. 1/4 Note; 2 = 1/2 Note. Im Beispiel wird eine halbe punktierte Note gespielt:
Play 24,2,1
PLAY wurde für die MIDI-Wiedergabe über die Soundkarte erweitert: Werden statt eines
Notenwertes mehrere durch Semikolon getrennt angegeben, werden diese gleichzeitig über
die verschiedenen Kanäle wiedergegeben. Die Kanäle 1 bius 16 entsprechen den MIDIKanälen mit dem Unterschied, das der 4. und 10. Kanal vertauscht wurden. Das Schlagzeug
befindet sich also bei General-MIDI jetzt auf Kanal 4, was das Erzeugen dreistimmiger Songs
mit Schlagzeugbegleitung vereinfacht.
Seite 292
RGH-PROFAN²
Wenn Dauer größer als 0 ist, werden die Töne entsprechend lang gespielt und das
Programm verharrt. Ist die Dauer 0, wird der Ton angestoßen und der Ton klingt im
Hintergrund solange bis er ausgeschaltet wird. Ausgeschaltet wird ein Ton, indem mit
vorangestelltem Minus-Zeichen ausgegeben wird.
Ist die Dauer -1, wird kein Ton erzeugt, sondern die Werte N1 bis N16 als Instrumente
interpretiert, die den 16 Kanälen zugewiesen werden. Das Beispiel spielt einen C-Akkord
(25;27;29) auf der Kirchenorgel (20. Instrument / Die Zählung beginnt hier bei 0) solange, bis
eine Taste gedrückt wird:
Play 19;19;19,-1,0
Play 25;27;29,0,0
WaitKey
Play -25;-27;-29,0,0
HINWEIS: Dieser Befehl funktioniert in der 16-Bit-Version auch ohne Soundkarte und
benutzt dann den internen Lautsprecher. Befehle mit einer Dauer kleiner als 1 werden dann
jedoch ignoriert und bei mehreren Notenwerten wird nur der erste benutzt.
PlaySound S,N
S : String - Dateiname (mit Pfad)
N : Integer - Spielmodus
Eine WAV-Datei wird über die Soundkarte (oder den SPEAKER-Treiber) abgespielt. Ist kein
Soundtreiber vorhanden, passiert nichts.
Beispiel:
PlaySound "C:\MMDATA\GONG.WAV",1
Mögliche Werte für N:
01816 -
Die Sound wird im Vordergrund gespielt. Das Programm wird
solange angehalten.
Die Sound wird im Hintergrund gespielt. Das Programm läuft
weiter.
Ein Sound wird solange wiederholt, bis ein neuer gestartet wird.
Der Sound wird nur gestartet, wenn kein anderer z.Zt. gespielt
wird.
Kombinationen sind durch Addition möglich. Bei 8+0 gibts keine Wiederkehr!
PopUp S
S : String - Name des Menüs
Ein PopUp-Menü wird an das FensterMenü angehängt. Existiert noch kein Fenstermenü, so
wird es erzeugt.
PopUp "&Datei"
AppendMenu "&Laden"
AppendMenu "&Speichern"
PopUp "&Bearbeiten"
...
Seite 293
RGH-PROFAN²
Print #N,f;f,f ...
N : Wert - Dateikennzeichen (1..15)
f : druckbarer Ausdruck
Der Ausdruck, bzw. die Ausdrücke werden in die mit N bezeichnete Datei geschrieben. Steht
zwischen den Ausdrücken ein Semikolon, so werden sie direkt aneinander gehängt, bei
einem Komma wird ein Leerzeichen eingefügt.
Siehe auch unter ASSIGN, REWRITE, APPEND und CLOSE.
Print f;f,f...
f : druckbarer Ausdruck
Der Ausdruck, bzw. die Ausdrücke werden auf den Bildschirm geschrieben. Steht zwischen
den Ausdrücken ein Semikolon, so werden sie direkt aneinander gehängt, bei einem Komma
wird ein Leerzeichen eingefügt. Siehe auch unter LOCATE. Beispiel:
Print "Dies ist der",N%;". Test"
Proc <Name> ... EndProc
<Name> : Name der Prozedur
Eine Prozedur wird definiert, die im nachfolgenden Programm wie ein neuer Befehl verwandt
werden kann. Über den PARAMETERS-Befehl werden die übergebenen Parameter
eingelesen.
Beispiel:
PROC Wiederhole
PARAMETERS Text$, Anzahl%
DECLARE I%
LET I%=0
WHILE @LT(I%,Anzahl%)
PRINT Text$
INC I%
WEND
ENDPROC
Wiederhole "Testtext",10
Die in der Prozedur über PARAMETERS oder DECLARE deklarierten Variablen sind nur
innerhalb der Prozedur bekannt (lokal). Alle Variablen, die außerhalb (oberhalb) der
Prozedur definiert wurden sind in der Prozedur auch bekannt (wie in PASCAL). Die Prozedur
kann auch schon vor Erreichen der Zeile ENDPROC über RETURN verlassen werden, wobei
dann die Übergabe eines Wertes an das aufrufende Programm möglich ist.
Seite 294
RGH-PROFAN²
PutByte #N1,N2
#N1: Dateikennung (1 - 15)
N2: Integer - zu schreibender Wert (0 ... 255)
Das Byte N2 wird an die aktuelle Position des Dateizeigers in die Datei mit der Kennung #N1
geschrieben und der Dateizeiger um 1 weitergesetzt. Befindet sich dadurch der Zeiger hinter
dem Ende der Datei, liefert @EOF(#N) den Wert 1. Durch weitere Schreiboperationen mit
PUTBYTE würde die Datei vergößert werden.
Siehe auch: @GetByte
PutClip S
S : String
Schreibt die Zeichenkette S (es kann auch ein numerischer Wert sein) als Text in die
Zwischenablage. Beispiele:
PutClip "Das ist ein Test!"
PutClip Text$
Die Zwischenablage wird vor dem Schreiben nicht gelöscht.
Mittels der Zwischenablage können somit Daten zwischen verschiedenen Programmen
ausgetauscht werden. Es ist sogar denkbar, daß ein Programm ein anderes über die
Zwischenablage fernsteuert.
Siehe auch: ClearClip @GetClip$()
Seite 295
RGH-PROFAN²
Randomize
Sorgt dafür, daß die Zufallszahlen (@RND) auch wirklich zufälligen Charakter haben.
ReadText V,S
V: Bereichsvariable
S: String - Dateiname (ggf. mit Pfad)
Die Textdatei S wird komplett in den Speicherbereich (beginnend ab Offset-Adresse 0)
eingelesen. Die Zeilen werden mit CR/LF (Zeichen 13 + 10) getrennt. Am Ende wird ein NullByte angehängt. Paßt der Text nicht in den mit DIM zugewiesenen Bereich, wird er
abgeschnitten und es erfolgt eine Warnung.
Rectangle X1,Y1-X2,Y2
X1,Y1 : Wert - Links oben
X2,Y2 : Wert - Rechts unten
Es wird ein Rechteck innerhalb der angegebenen Koordinaten gezeichnet.
Rem ...
Alles was dahinter steht, ist Kommentar. REM steht immer am Anfang der Kommentarzeile.
Für Kommentare hinter anderen Befehlen ist das ' zu benutzen.
RemoveMenu N
N: Integer - Menüpunkt
Der Menüpunkt mit der Nummer N wird aus dem aktuellen Fenster-Menü entfernt.
Rename #N,S
N : Wert - Dateikennzeichen (1..15)
S : String - neuer Name (mit Pfad)
Die Datei mit dem Kennzeichen N wird in S umbenannt. Enthält S eine Pfadangabe (mit oder
ohne Laufwerksbezeichnung), so wird sie verschoben. Verschieben ist nur innerhalb eines
Laufwerks möglich. Beispiel:
Assign #3,"C:\TEST.DAT"
Rename #3,"C:\UTILS\TOAST.DAT"
RePaint
Malt den Bildschirm neu. Ist nur dann zu benutzen wenn bestimmte Befehlskombinationen
(u.U. in Zusammenhang mit PopUp-Windows) den Bildschirm etwas durcheinander bringen.
Dies sollte in der aktuellen PROFAN²-Version nicht mehr vorkommen.
Seite 296
RGH-PROFAN²
Reset #N
N : Wert - Dateikennzeichen (1..15)
Die Datei N wird zum Lesen geöffnet. Beispiel:
Declare Zeile$ Assign #2,"TEST.DAT"
Reset #2
WhileNot @Eof(#2)
Input #2,Zeile$
Print Zeile$
Wend
Siehe auch: Rewrite, Append und OpenRW.
Return [<Wert>]
Beenden einer Prozedur. Es ist möglich einen Wert zurückzugeben. Dieser steht dann in
@$(0), @%(0), @&(0) und/oder @!(0):
PROC Test
Print "Das ist ein Test"
Return "OK!"
ENDPROC
Print "Im Hauptprogramm"
Test
Print "Wieder zurück! Ergebnis:",@$(0)
Der zurückgegebene Wert darf im Falle einer Prozedur auch eine lokale Variable sein.
WICHTIG: Auch wenn eine Prozedur mit RETURN verlassen wird, muß die Definition der
Prozedur mit ENDPROC abgeschlossen werden.
Rewrite #N
N : Wert - Dateikennzeichen (1..15)
Die Datei N wird zum Schreiben geöffnet. Der bisherige Dateiinhalt geht verloren. Existiert
sie nicht, wird sie erzeugt. Beispiel:
Assign #2,"C:\UTILS\TEST.DAT"
Rewrite #2
Print #2,Zeile$
Close #2
Um eine bestehende Datei zu erweitern, ist der Befehl APPEND zu verwenden.
Siehe auch: Reset und OpenRW.
RmDir S
S : String - Verzeichnisnamen
Das Verzeichnis S wird gelöscht. Enthält es noch Dateien oder Unterverzeichnisse, kann es
nicht gelöscht werden. Bei erfolgreicher Operation hat %IORESULT den Wert 0.
Sie auch: ChDir MkDir
Seite 297
RGH-PROFAN²
RoundRect X1,Y1-X2,Y2; X3,Y3
X1,Y1 : Wert - Links oben
X2,Y2 : Wert - Rechts unten
X3,Y3 : Wert - Rundung
Es wird ein abgerundetes Rechteck gezeichnet. X1,Y1 und X2,Y2 bezeichnen das Rechteck,
die anderen Parameter den Grad der Rundung in waagrechter und senkrechter Richtung.
Run S
S : String - Programmname
Das Programm S wird aufgerufen und das aufrufende Profanprogramm beendet. Es können
alle Windowsprogramme - auch mit Parametern - aufgerufen werden. Beispiele:
Run "NOTEPAD HILFE.TXT"
Run "E:\PROFAN\PROFAN DEMO.RGH"
Run "WRITE"
Seite 298
RGH-PROFAN²
SaveBmp S,X1,Y1-X2,Y2
S: String - Dateinahme (mit Pfad)
X1,Y1: Integer - linke obere Ecke
X2,Y2: Integer - rechte untere Ecke
Der angegebene Teil des Bildschirmes wird in eine BMP-Datei gespeichert. Die Dateiendung
".BMP" ist mit anzugeben. Beispiel:
SaveBmp "TESTBILD.BMP",10,10-200,140
SaveBmpToClip X,Y - DX,DY
X,Y : Integer - linke obere Ecke
DX,DY: Integer - Größe des zu speichernden Bildes
Der angegebene Teil des Bildschirmes wird in die Zwischenablagew gespeichert. Von dort
aus kann die Bitmap von anderen Programmen benutzt werden.
Screen X,Y
X,Y
: Ausmaße des virtuellen Screens
Das Koordinatensystem des Hauptfensters bzw. des mit STARTPAINT aktivierten Fensters
wird auf Breite X und Höhe Y festgelegt. Alle weiteren Koordinatenangaben beziehen sich
auf das mit Screen eingestellte Koordinatensystem. Auf diese Weise sind
Bildschirmausgaben möglich, die sich immer an die aktuelle Fenstergröße anpassen. Die
dritte Zeile des Beispiels setzt das Koordinatensystem wieder auf Angaben in Pixel zurück:
Cls
Screen 3000,2000
Line 10,10 - 2900,1900
Screen Width(%Hwnd),Height(%Hwnd)
WaitInput
ScreenCopy [X1,Y1-X2,Y2]
X1,Y1: Integer - linke obere Ecke
X2,Y2: Integer - rechte untere Ecke
Der angegebene Bereich wird auf den Drucker kopiert und die Seite ausgedruckt. Ist kein
Bereich angegeben, wird der gesamte Bildschirm ausgedruckt. Beispiele:
ScreenCopy 10,10 - 600,100
ScreenCopy
Siehe auch das Befehlspaar STARTPRINT ... ENDPRINT und WINCOPY.
Seek #N,A
#N: Dateikennung (1 - 15)
A: LongInt - Position in der Datei
Der Dateizeiger der im Binärmodus geöffneten Datei mit der Kennung #N wird auf die
Position A gesetzt. Das erste Byte in der Datei hat die Position 0. Hinweis: SEEK
Seite 299
RGH-PROFAN²
#N,@GETFILESIZE(#N) setzt den Zeiger hinter das letzte Byte. Damit wird die Datei
vergrößert.
Separator
Fügt dem PopUp-Menü eine Trennungslinie hinzu. Beispiel:
PopUp "&Datei"
AppendMenu
AppendMenu
AppendMenu
AppendMenu
Separator
AppendMenu
100,"&Neu"
101,"&Laden"
102,"&Speichern"
103,"Speichern &als"
104,"&Ende"
Seite 300
RGH-PROFAN²
SetAutoPaint N
N
: Integer - 0: AutoPaint ist ausgeschaltet, %wmPaint wird immer gesetzt
1: AutoPaint ist eingeschaltet, von Dialogfenstern wird %wmPaint gesetzt
2: AutoPaint ist eingeschaltet, %wmPaint wird niemals gesetzt (Standard)
Wenn ein Fenster vergrößert und/oder verschoben wird, müssen Teile des Bildschirmes
und/oder Fensters neu gezeichnet werden. Im Normalfall nimmt Ihnen PROFAN² diese
Arbeit ab, indem es auf die entsprechende Aufforderung durch Windows reagiert. Solange in
den Dialogboxen und Dialogfenstern nicht gezeichnet wird (siehe StartPaint - EndPaint),
benötgt das PROFAN²- Programm also keine Kenntnis über diese Aufforderung.
Wenn man in Dialogfenstern zeichnet, so übernimmt hier PROFAN² das Neuzeichnen nicht
automatisch. Mit SetAutoPaint 1 sorgt man nun dafür, daß die Aufforderung zum
Neuzeichnen eines Dialogfensters WaitInput verläßt und die Systemvariable %wmPaint
gesetzt wird. Das Hauptgfenster wird in diesem Fall weiterhin von PROFAN² automatisch
versorgt.
Es mag nun aber Fälle geben, wo der fortgeschrittene Programmierer auch dieses selbst in
die Hand nehmen möchte, etwa weil er die Größe der Hintergrundbitmap immer an die
Größe des Haupfensters angepaßt haben möchte. Dazu kann er mit SetAutoPaint 0 das
automatische Aktualisieren des Bildschirmes ausschalten und es selber übernehmen.
%wmPaint wird nun auch gesetzt, wenn das Hauptfenster neu gezeichnet werden muß.
Folgendes Beispielprogramm zeigt eine Bitmap immer in der Größe des Programmfensters
an und wird mit "Esc" beendet:
Declare Ende%
PROC MaleNeu
MCopySizedBmp 0,0-32,32 > 0,0-Width(%HWnd),Height(%HWnd);0
ENDPROC
SetAutoPaint 0
CLS
MLoadBmp "TEST.BMP"
MaleNeu
Let Ende% = 0
WHILENOT Ende%
WaitInput
IF @Equ(%Key,27)
Let Ende% = 1
ELSEIF %wmPaint
MaleNeu
ENDIF
ENDWHILE
END
SetCheck N1,N2
N1 : Integer - Handle des Fensterobjektes
N2 : Integer - 1 = setzen / 0 = zurücksetzen
Die Checkbox bzw. der Radiobutton mit dem Handle N wird gesetzt (angekreuzt), bzw.
zurückgesetzt.
Seite 301
RGH-PROFAN²
SetDialogFont N
N:Integer - Modus (0 = Systemfont / 1 = gewählter Font)
Hat N den Wert 1 wird für die nachfolgend erstellten Dialogelemente (mit @CREATE...) der
mit USEFONT eingestellte Font benutzt. Ansonsten wird - wie bisher - der Systemfont
verwandt.
SetErrorLevel N
N: Integer - Errorlevel
Je nach Wunsch kann der Errorlevel auf einen der möglichen Werte gesetzt werden. Damit
wird das Verhalten des Systems bei Auftreten eines Fehlers oder einer Warnung definiert:
210-1 -
Für ganz Vorsichtige: Warnungen werden wie Fehler behandelt und führen zu
einer Fehlermeldung mit Programmabbruch.
Für die Programmentwicklung: Auch Warnungen werden ausgeben, aber das
Programm läuft auf Wunsch weiter.
Der Normalzustand: Warnungen werden nicht angezeigt. Diesen Errorlevel sollte
man bei einem fertigen Programm verwenden.
Fast schon kriminell: Auch Fehlermeldungen werden übergangen.Das kann unter
Umständen zu einem Windowsfehler oder Absturz desSystemes mit Datenverlust
führen.
Warnungen treten auf, wenn ein Ausdruck nicht als numerischer Wert zu interpretieren ist
oder z.B. eine Bilddatei nicht gefunden wird ...
SetFAttr #N1,N2
#N1: Dateikennung
N2: Integer - Attribut(e)
Setzt das Attribut der Datei #N. Der Kennung #N muß eine Datei mit ASSIGN zugewiesen
worden sein. Die Datei darf aber nicht geöffnet sein. Geöffnet wird eine Dartei durch die
Befehle REWRITE, APPEND, RESET oder OPENRW. Die Attribute:
$01 = ReadOnly
$02 = Hidden
$04 = SystemDatei
$08 = Label
$10 = Directory-Eintrag
$20 = Archiv
Werden mehrer Attribute verwandt, so sind sie zu addieren.
Seite 302
RGH-PROFAN²
SetLFN N
N: Integer - -1, 0 oder 1 (nur 16-Bit-Version)
Die Benutzung von langen Dateinamen wird bestimmt:
-1
0
1
Das System erkennt automatisch, ob Windows 95 (oder neuer) aktiv ist.
Lange Dateinamen sind ausgeschaltet
lange Dateinamen sind eingeschaltet
Bei Windows 3.x führt das Einschalten der langen Dateinamen unweigerlich zu einem
Systemfehler, daher ist diese Einstellung mit Vorsicht zu genießen. Der Befehl ist dafür
gedacht, lange Dateinamen dort zu erlauben, wo die automatische Erkennung dieser
Fähigkeit versagt, z.B. unter Windows 3.x NT.
Wird SetLFN auf 0 oder 1 gesetzt, zeigt dies die Systemvariable %LFN auch entsprechend
an. Bei -1 zeigt sie das Ergebnis der automatischen Erkennung an.
WICHTIG: In der 32-Bit-Version von PROFAN ist dieser Befehl ohne Wirkung!
SetMenuItem N
N: Integer - Menünummer
Die Systemvariable %MENUITEM, die auch von der Funktion @MENUITEM ausgewertet
wird, wird auf den Wert N gesetzt.
SetPixel X,Y,C
X,Y : Wert - Koordinaten
C : Wert - RGB-Farbewert
Setzt an die Position X,Y ein Pixel in der Farbe C (bzw. der C am nächsten liegenden
darstellbaren Farbe). Beispiel:
SetPixel 10,10,@RGB(13,20,3)
SetPixel 11,11,0
SetScrollPos N1,N2
N1: Integer - Handle des Scrollbalkens
N2: Integer - Wert
Der Wert des Scrollbalkens (und damit der Schieberegler) wird gesetzt. Zum Auslesen des
Wertes ist die Funktion @GETSCROLLPOS zu verwenden.
SetScrollRange N1,N2,N3
N1: Integer - Handle des Scrollbalkens
N2: Integer - niedrigster Wert (-32767 - 32767)
N3: Integer - höchster Wert (-32767 - 32767)
Der Wertebereich des Scrollbalkens wird gesetzt. Niederigster und höchster Wert dürfen
nicht mehr als 32767 auseinanderliegen! Standardmäßig ist der Wertebereich eines
Scrollbalens auf 0 - 100 eingestellt.
Seite 303
RGH-PROFAN²
SetText N,S
N : Integer - Handle des Fensterobjektes
S : String - Neuer Text
Dem Fensterobjekt mit dem Handle N% wird der Text S$ zugewiesen. Bei einem Eingabeoder Textfeld ist das der Text im Feld. Bei einem Iconfeld der Name des Icons, bei einem
Button der Text der Schaltfläche, bei einem Fenster der Fenstertitel, ...
Mit @GETTEXT$ kann dieser Text ausgelesen werden.
Dieser Befehl ist nur in der Vollbersion vorhanden!
SetTimer N - KillTimer
N
: LongInt - Timer-Intervall in Millisekunden
Mit SetTimer wird ein Zeitgeber eingestellt, der alle N Millisekunden ein Timer-Ereignis
ausgelöst. Dieses Ereignis führt dazu, daß ggf. ein WAITINPUT verlassen wird und die
Systemvariable %wmTimer auf 1 gesetzt wird. Erst beim Auslesen wird sie wieder auf 0
gesetzt. Da die Anzahl der möglichen Zeitgeber in Windows sehr begrenzt ist, erlaubt
PROFAN² nur die Nutzung eines Zeitgebers, was aber in aller Regel ausreichend ist. Es ist
durchaus statthaft, den Zeitgeber mit einem erneuten SetTimer neu einzustellen. Vor dem
Enden des Programmes muß der Zeitgeber, so er im Programm mindestens einmal genutzt
wurde, mit KillTimer wieder freigegeben werden. Folgendes Beispiel zeigt eine Schleife, die
erst nach 10 Sekunden (= 10000 Millisekunden) verlassen wird, aber den Prozessor nicht
belastet:
PROC Schlafe
Parameters N&
Declare Ende%
SetTimer N&
Let Ende% = 0
WHILENOT Ende%
WaitInput
Case %wmTimer:Let Ende% = 1
ENDWHILE
KillTimer
ENDPROC
CLS
Print "Der Timer startet ..."
Schlafe 10000
Print "... und weiter geht's"
WaitKey
End
Hinweis: Das Timerereignis wird nur ausgelöst, wenn ein Hauptfenster existiert.
Tip: Man kann auch unsichtbare Hauptfenster (Windowstyle 112, Größe 0,0-0,0) erzeugen.
Seite 304
RGH-PROFAN²
SetTrueColor N
N: Integer - 0 oder 1
0 - 32768 Farben
1 - 16 Millionen Farben
Standardmäßig nutzt PROFAN bei den eigenen Zeichenbefehlen 32768 Farben, wobei der
Rot-, Grün- und Blau-Anteil zwischen 0 und 31 liegen darf. Mit SETTRUECOLOR 1 wird auf
16 Millionen Farben umgeschaltet, wobei die Farb- anteile jetzt zwischen 0 und 255 liegen
dürfen.
SetWindowPos W=X,Y-DX,DY
W: Integer - Fensterhandle
X,Y: Integer - Linke obere Ecke des Fensters
DX,DY: Integer - Neue Größe des Fensters
Die Position und Größe des Fensters bzw. Fensterobjektes mit dem Handle W wird auf die
neuen Werte gesetzt. Dieser Befehl kann natürlich auf jedes Windowsobjekt, dessen Handle
bekannt ist, angewandt werden!
Shell S
S : String - Programmname
Das Programm S wird aufgerufen und das aufrufende Profanprogramm läuft weiter. Es
können alle Windowsprogramme - auch mit Parametern - aufgerufen werden. Beispiel:
Shell "NOTEPAD HILFE.TXT"
Vergleiche auch: Run, @WinExec
ShowCursor N
N : Integer - 0 = verstecken / 1 = anzeigen
Der Kursor kann versteckt oder gezeigt werden. Bei Bildschirmschonern ist in der Regel kein
sichtbarer Mauskursor gewünscht. Jede Anwendung, die den Kursor versteckt, sollte ihn
auch wieder anzeigen.
1 - Der Kursor wird angezeigt
0 - Der Kursor wird versteckt
ShowMax
Das Bildschirmfenster wird zu seiner Maximalgröße erweitert. Der Befehl ist identisch mit
dem Anklicken des Pfeiles nach oben an der rechten oberen Ecke des Rahmens.
Seite 305
RGH-PROFAN²
ShowMin
Das Profanprogramm wird zum Icon verkleinert und läuft allerdings weiter. Vergrößert wird
es entwededer durch SHOWNORMAL oder SHOWMAX oder aber durch entsprechendes
Auswahl im Systemmenü [-] des Programmes.
ShowNormal
Das Bildschirmfenster des Profanprogrammes wird in normaler Größe angezeigt, das heißt
z.B. in der Größe, die es vor dem Verkleinern (zum Icon) oder Vergrößern hatte.
Vergleiche auch: @ShowWindow
Sound N1,N2
N1 : Wert - Frequenz in Hertz
N2 : Wert - Dauer in 360tel Sekunden
Es wird ein Ton mit angegebener Frequenz und Dauer ezeugt und über den Lautsprecher
wiedegegeben. Während der Tonerzeugung wird das Programm angehalten. Folgende Zeile
spielt eine Sekunde lang den Kammerton A:
SOUND 440,360
HINWEIS: Dieser Befehl funktioniert nicht in der 32-Bit-Version unter Windows 95, da die
Windows 95 - API nicht mehr die Wiedergabe von Tönen über den Lautsprecher vorsieht.
Unter Windows NT hingegen sollte es funktionieren.
Seite 306
RGH-PROFAN²
SQLExec S,N
S - String: SQL-Befehl
N - Integer: Ergebnismodus
Sendet einen SQL-Befehl an die Datenbank. S ist das
Ergebnismodus:
0:
1:
2:
SQL-Statement und N der
Das Ergebnis wird angezeigt. Jeder Datensatz ist ein Zeile und kann maximal
255 Zeichen enthalten.
Das Ergebnis wird in die Listbox-Liste geschrieben und kann dann z.B. mit
der @LISTBOX$-Funktion betrachtet werden. Jeder Datensatz ist ein Eintrag
in der Liste und kann maximal 255 Zeichen enthalten; maximal 10000 Datensätze
passen in die Liste.
Das Ergebnis wird in die Datei "SQL.DAT", die im aktuellen Pfad erzeugt wird,
geschrieben. Jeder Datensatz ist eine Zeile.
In &SQLCOUNT wird zurückgeliefert, wieviele Datensätze bearbeitet wurden oder -1, wenn
ein Fehler auftrat.
Beispiel:
SQLEXEC "SELECT * FROM KUNDEN",1
SQLSetNULL S
S - String: NULL-Zeichen
Legt fest, das NULL als S im Ergebnis dargestellt wird. Ein Datensatzfeld hat den Wert
NULL, wenn ihm kein Wert zugewiesen wurde. NULL steht also für nichts.
SQLSetDel S
S - String: Trennzeichen
Legt fest, mit welchem Zeichen die einzelnen Felder im Ergebnis getrennt werden.
Voreingestellt ist "|". Wenn S zwei Zeichen groß ist, legt das zweite Zeichen fest, mit
welchem Zeichen die Feldinhalte begrenzt werden. Voreingestellt ist hier der Leerstring.
Das zweite Zeichen wirkt nur, wenn das Ergebnis des SQL-Befehles in eine Datei
ausgegeben wird (Modus 2). Will man zum Beispiel erreichen, daß in der Ergebnisdatei die
Feldinhalte in Anführungszeichen stehen und die Felder mit einem Komma getrennt
werden, müßte S$ die Zeichen , und " enthalten:
SQLSETDEL @ADD$(",",@CHR$(34))
SQLDone
Der Befehl beendet die Verbindung zum SQL-Server und gibt die von ODBC.DLL belegten
Speicherbereiche wieder frei.
Seite 307
RGH-PROFAN²
StartPaint H - End Paint
H
: Integer - Handle des Fensters, in das gezeichnet werden soll / -1 = Memorybitmap
Mit diesem Befehl können die Bildschirmausgaben auf ein anderes Fenster, etwa eine
DialogBox oder ein DialogFenster umgeleitet werden. (Von der Umleitung ausgeschlossen
sind jene Befehle, die den Textmodus von PROFAN² betreffen, wie etwa LOCATE, PRINT,
TBOX, ...) So ist es nun möglich in beliebige Fenster, deren Handle man hat, zu malen, Text
auszugeben, Bitmaps zu laden, etc.
WICHTIG: Jedem StartPaint muß (!) ein EndPaint folgen. Nach dem EndPaint erfolgen dies
Ausgaben wieder auf das Hauptfenster. Während der Druckausgabe mit StartPrint - EndPrint
ist der Befehl verboten.
Wenn als Fensterhandle -1 angegeben wird erfolgt die Ausgabe in ein "unsichtbares
Fenster", nämlich in die Memorybitmap, die mit MCLS oder MLOADBMP erzeugt wurde.
Beim Zeichnen in DialogBoxen und DialogFenstern ist zu beachten, daß diese Zeichnungen
nicht automatisch erneuert werden, wenn die Dialogbox z.B. durch ein anderes Fenster
verdeckt wurde. Auch wenn AutoPaint eingeschaltet ist, erzeugen DialogBoxen und
DialogFenster eine wm_Paint-Botschaft, die ggf. das WaitInput verläßt und die
Systemvariable %wmPaint auf 1 setzt.
Wenn AutoPaint mit SetAutoPaint 0 komplett ausgeschaltet ist, ist es durchaus sinnvoll (aber
nicht notwendig) die Ausgaben auf das Hauptfenster auch in StartPaint - EndPaint
einzuschließen, wobei dann als Fensterhandle %Hwnd zu nehmen ist.
StartPrint [S] ... NextPage ... EndPrint
Zwischen diesen beiden Befehlen werden alle grafischen Bildschirmausgaben (DRAWTEXT,
RECTANGLE, ...) auf eine Druckeseite ausgegeben. "Textmodus"- und einige BitmapBefehle sind nicht gestattet. LOADBMP und LOADSIZEDBMP funktionieren hingegen wie
gewohnt und sind ideal um Bitmap-Grafiken zu drucken. Mit ENDPRINT wird der Druck der
Seite veranlaßt. Die Druckseite hat horizontal eine Weite von 640 Punkten und senkrecht
eine Höhe von 960 Punkten. (Der Drucker sollte auf DIN A4 - Hochformat eingestellt sein.)
Wahlweise kann dem Druckauftrag mit dem Strinparameter S ein Name gegeben werden,
der anstatt des Standartnamens im Druckmanager erscheint.
Mit NEXTPAGE wird innerhalb des Druckauftrages zwischen STARTPRINT und ENDPRINT
eine neue Seite begonnen.
String V,A=S
V: Bereichsvariable
A: Integer - Adresse in der Bereichsvariablen
S: String - Zeichenkette
Der String S wird im Speicherbereich V ab Adresse (Offset) A abgelegt. Das Ende des
Strings wird durch ein Null-Byte gekennzeichnet. Paßt der String nicht mehr ganz in den mit
DIM zugewiesenen Bereich, wird er entsprechend abgeschnitten. Liegt A außerhalb des
Bereiches erfolgt eine Fehlermeldung.
HINWEIS: Sollen mehrere Strings in einen Bereich geschrieben werden, ist darauf zu
achten, daß sich die Strings nicht überschreiben. Dabei ist zu berücksichtigen, daß ein
String für jedes Zeichen ein Byte belegt plus ein zusätzliches Byte für das abschließende
Byte mit dem Wert 0!
Seite 308
RGH-PROFAN²
StrWidth N
N: Integer (Mindestweite)
Die Mindest-Ausgabeweite für Strings (mittels des PRINT-Befehles) wird festgelegt. Strings,
die kürzer als N sind, werden entsprechend mit vorangestellten Leerzeichen verlängert.
Voreingestellt ist der Wert 0 (= "normales" Verhalten der Strings).
Sub VAR,N
VAR - Variablenname (Integer)
N - Integer
N wird von Variablen VAR subtrahiert. (Ist schneller und einfacher als die @SUB-Funktion.)
Beispiel:
SUB Punkte%,10
SubPopUp ... EndSub
Ein Untermenü zu einem Popup-Menü wird erzeugt. Eine Verschachtelung ist (bis zu einer
Tiefe von 10) möglich:
...
AppendMenu 210,"&Auswahl 3"
SubPopUp "&Schriften ..."
AppendMenu 211,"Schrift &1"
AppendMenu 212,"Schrift &2"
...
EndSub
AppendMenu ...
Seite 309
RGH-PROFAN²
TBox X1,Y1 - X2,Y2; N
X1,Y1 : Wert - linke obere Ecke
X2,Y2 : Wert - rechte untere Ecke
N : Rahmentyp
Es wird im Textmodus eine Box gezeichnet. Die Koordinaten werden wie bei LOCATE in
Zeichen eingegeben. Benutzt werden die Grafikzeichen des OEM-Zeichensatzes.
0 - Einfacher Rahmen
1 - Doppelter Rahmen
2 - Senkrecht doppelt/waagrecht einf.
3 - Ohne Rahmen
TextColor C1,C2
C1 : Wert - Vordergrundfarbe (RGB)
C2 : Wert - Hintergrundfarbe (RGB)
Die Farben für die Ausgabe mittels DRAWTEXT werden festgelegt. Bei -1 als
Hintergrundfarbe, ist diese transparant, d.h. der vorhandene Hintergrund wird genommen.
Beispiel:
TextColor @RGB(15,15,31),-1
DrawText 23,67,"Hugo was here!"
TraceON
TRACEON schaltet in den TRACE-Modus. Vor Abarbeitung einer Zeile wird diese in einer
Messagebox angezeigt. Mit "Abbrechen" kann das Programm beendet werden. Der Befehl ist
nur im Interpreter sinnvoll und daher im Runtimemodul bzw. bei compilierten Programmen
wirkungslos.
TraceOFF
TRACEOFF schaltet den TRACE-Modus aus.
TrackMenu X,Y
X,Y : Wert - Position
Das Programm zeigt das mit CREATEMENU und APPENDMENU erzeugte Menü an der
gewünschten Position an und erwartet die Auswahl. Das Ergebnis steht in %MENUITEM.
Beispiel:
TrackMenu 20,130
Case %MenuItem(100):Gosub "Speichern"
Case %MenuItem(120):End
Seite 310
RGH-PROFAN²
UseBrush N,C
N : Wert - Art des Pinsels
C : Wert - Farbe des Pinsels (RGB)
Der Pinsel wird benutzt, um die Grafiken (RECTANGLE, ROUNDRECT, etc.) auszufüllen. C
ist die benutzte RGB-Farbe (0 ... 32767), N bezeichnet die Art des Pinsels:
0 : Transparant (nicht ausgefüllt)
1 : Solid (voll gefüllt)
2 .. 8 : verschiedene Schraffuren
Schraffuren:
2 - waagrecht =====
3 - senkrecht |||||
4 - diagonal \\\\\
5 - diagonal /////
6 - kariert #####
7 - diag.kar. XXXXX
Die Schraffur wird in der Farbe C ausgeführt.
UseCursor N
N : Wert - Cursortyp (0 .. 11)
Ändert das Aussehen des Mauszeigers. Es sind alle 11 von Windows vorgegebenen
Mauszeiger verwendbar und zusätzlich ein Druckersymbol (während des Druckens.). Der
Sanduhr-Zeiger sollte immer dann eingesetzt werden, wenn der Anwender warten muß und
eh' keine Eingaben machen kann, z.B. beim Speichern und Laden.
Die Bedeutung von N:
0 - Zeiger (Standard)
1 - Texteingabe (senkr. Strich)
2 - Sanduhr (Bitte warten ...)
3 - Fadenkreuz
4 - Großer senkrechter Pfeil
5 - Vierfach-Pfeil (+)
6 - Icon (kleines Quadrat in Größerem
7 - Doppel-Pfeil (\)
8 - Doppel-Pfeil (/)
9 - Doppel-Pfeil (-)
10 - Doppel-Pfeil (|)
11 - Drucker
Vergleiche auch: ShowCursor
Seite 311
RGH-PROFAN²
UseExtCursur I,S
I
S
: Integer - Instanzhandle der EXE bzw. DLL,
die den Cursor enthält
: String - Name des Cursors
Das Instanz-Handle wird bei DLLs mittels @UseDLL ermittelt und bei EXE-Dateien mittels
@WinExec. Das Handle des ausführenden Programmes ist in der Systemvariablen
%HInstance. Es ist also möglich, alle in einem Programm verwandten Mauszeiger mittels
eines Tools wie des Resource-Workshops von Borland in eine DLL zu packen. Ebenso ist es
z.B. möglich, die PROFRUN.EXE vor dem Linken entsprechend zu erweitern.
Vergleiche auch: UseCursor, ShowCursor
UseExtMenu I,S
I
S
: Integer - Instanzhandle der EXE bzw. DLL,
die das Menu enthält
: String - Name oder Nummer des Menüs
Das Instanz-Handle wird bei DLLs mittels @UseDLL ermittelt und bei EXE-Dateien mittels
@WinExec. Das Handle des ausführenden Programmes ist in der Systemvariablen
%HInstance. Es ist also möglich, alle in einem Programm verwandten Menüs mittels eines
Tools wie des Resource- Workshops von Borland in eine DLL zu packen. Ebenso ist es z.B.
möglich, die PROFRUN.EXE vor dem Linken entsprechend zu erweitern.
UseFont S,N1,N2,N3,N4,N5
S : String - Fontname
N1 : Wert - Zeichenhöhe
N2 : Wert - Zeichenbreite
N3 : Wert - Fett? (0 .. 1)
N4 : Wert - Kursiv? (0 .. 1)
N5 : Wert - Unterstrichen? (0 .. 1)
Der Font für die Ausgabe von Text mittels DRAWTEXT wird festgelegt.
N1: Zeichenhöhe. Steht hier 0, wird ein Defaultwert für Breite und Höhe genommen.
N2: Zeichenbreite. Steht hier 0, wird ein Defaultwert genommen
N3: 1 = fett , 0 = normal
N4: 1 = kursiv, 0 = normal
N5: 1 = unterstrichen, 0 = normal
UseIcon S
S : String - Name des Icons
Es wird das Icon ausgewählt, das für das Programm verwandt wird, wenn es verkleinert wird.
Standardmäßig ist es das Profan-Icon. Es kann aber jedes der 18 "eingebauten" Icons
verwandt werden.
Seite 312
RGH-PROFAN²
UsePen N1,N2,C
N1 : Wert - Linienart (0 .. 5)
N2 : Wert - Linienstärke
C : Wert - RGB-Farbe
Die hier eingestellten Werte werden von den Zeichenbefehlen für die Rahmen bzw. Linien
benutzt. Beispiel:
UsePen 1,5,@RGB(0,0,31)
Rectangle 10,10 - 150,100
Linienart:
0 - durchgezogen __________
1 - gestrichelt _ _ _ _ _ _
2 - gepunktet .............
3 - Strich-Punkt _._._._._.
4 - Strich-Punkt-Punkt _.._.._..
5 - keine Linie
Die Werte 1 bis 5 sind nur bei einer Strichstärke von 1 sinnvoll.
Seite 313
RGH-PROFAN²
WaitInput
Wartet auf einen Mausklick oder Tastendruck im Profan-Fenster. Das Ergebnis steht in den
Systemvariablen %MOUSEKEY, %MOUSEX, %MOUSEY, %SCANKEY und %KEY.
Außer auf Tastendrücken reagiert WAITKEY wie auch WAITINPUT noch auf folgende
Ereignisse und bestückt %Key entsprechend:
1
2
4
5
13
255
Es wurde ein Eintrag in einer Listbox angewählt oder es wurde ein Eintrag einer
Auswahlbox gewählt
Es wurde in einer Dialogbox bzw. einem Dialogfenster auf das Systemmenü
doppelgeklickt, bzw. "Schließen" ausgewählt
Ein Fenster des Programmes wurde in der Größe verändert
Es wurde F1 gedrückt, während der Fokus auf einem Dialogelement bzw. in einer
Dialogbox war. Das Handle des Elementes steht als negativer Wert in %GetFocus.
Es wurde in einem einzeiligen Editierfeld oder einer Listbox <Enter> gedrückt
Es wurde ein Button, eine Checkbox oder ein Radiobutton angeklickt
WaitKey
Wartet auf einen Tastendruck. Das Ergebnis steht in der Systemvariablen %KEY.
(Funktionstasten, sog. "virtuelle Tastencodes" werden nicht erkannt. Wird dies benötigt, ist
WAITSCAN zu verwenden.)
WaitMouse
Wartet, bis eine Maustaste (im Profan-Fenster) gedrückt wird. Welche Taste es war, und die
Position der Maus steht in den Systemvariablen %MOUSEKEY, %MOUSEX und
%MOUSEY.
WaitScan
Wartet auf einen beliebigen Tastendruck. Auch Funktionstasten, Kusortasten, Shift- und
Ctrltasten werden erkannt. Das Ergebnis steht in als virtueller Tastencode in %SCANKEY
und - im Falle einer "normalen" Taste - als ANSI- Code in %KEY.
Wichtige Scancodes:
16 17 27 33 34 35 36 37 38 39 40 45 46 112 ... 123 -
Shift
Strg
Esc
BildHoch
BildRunter
Ende
Pos1
Links
Hoch
Rechts
Runter
Einfg
Entf
F1
...
F12
Seite 314
RGH-PROFAN²
Die übrigen lassen sich durch Ausprobieren mit folgendem Programm leicht austesten:
Cls
While 1
'Endlosschleife!
WaitScan
Print %ScanKey
Wend
End
While N ... EndWhile
N : Wert - Bedingungsausduck
Die zwischen WHILE und WEND stehenden Befehle werden solange wiederholt, solange N
ungleich 0 ist. Beispiel:
While N%
Print "Gebe eine Zahl ein: ";
Input N%
Wend
Anstelle von ENDWHILE kann auch die von Basic her gewohnte Schreibweise WEND
verwandt werden.
WhileNot N ... EndWhile
N : Wert - Bedingungsausduck
Die zwischen WHILENOT und WEND stehenden Befehle werden solange wiederholt,
solange N gleich 0 ist. Beispiel:
WhileNot @Eof(#2)
Input #2,Zeile$
Print Zeile$
Wend
Window X1,Y1-X2,Y2
X1,Y1 : Wert - linke obere Ecke
X2,Y2 : Wert - Größe in Pixeln
Das Fenster wird in der angegebenen Größe geöffnet. X1 und Y1 sind absolute
Bildschirmkoordinaten. Jedes Programm, daß Ausgaben auf das Hauptfenster des PROFANProgrammes macht muß dieses entweder mit WINDOW oder CLS öffnen. Wenn CLS zum
Öffnen des Fensters verwandt wird, benutzt Profan den ganzen (Standard-VGA-)Bildschirm
(640 * 480 Pixel).
Seite 315
RGH-PROFAN²
WindowStyle N
N : Wert - Stil des Fensters (0 ... 255)
Das Aussehen des Programmfensters wird festgelegt. Folgende Eigenschaften können
definiert werden:
1
2
4
8
16
32
64
128
512
- Fenster hat Vergrößerungsbox (Pfeil nach oben) und kann vergrößert werden
- Fenster hat Verkleinerungsbox (Pfeil nach unten) und kann zum Icon werden
- Dicker Rahmen (Größe des Fensters ist veränderbar)
- Fenster hat System-Menü
- Fenster hat zunächst kein Menü (also auch kein ©)
- Fenster benutzt Bildschirmhintergrund als Hintergrund
- Das Fenster hat keine Titelzeile
- Das Programm kann weder mit <Strg-Esc>, <Alt-Tab> noch <Alt-F4>
verlassen werden.
- Dialogfensterstil für Hauptfenster (s.u.)
Kombinationen werden durch Addition der einzelnen Werte erreicht. Damit der Befehl
Wirkung zeigt, muß er vor dem ersten Öffnen des Programmfensters erfolgen! Soll der
Bildschirmhintergrund als Hintergrund verwandt werden, muß das Fenster mit WINDOW
(und nicht mit CLS) geöffnet werden. Beispiel:
WindowStyle 31
Ideal für Bildschirmschoner:
WindowStyle $F0
Der Dialogfenster-Stil (512 bzw. $200) erlaubt es, daß Dialogelemente auf einem
Hauptfenster erbenso reagieren, wie in einem Dialogfenster, d.h. es kann mit TAB zwischen
Ihnen umgeschaltet werden, Buttons reagieren nur beim Loslassen des Knopfes, etc. Ebenso
wie ein Dialogfenster regiert das Hauptfenster nun auch nicht mehr auf das Schließen des
Fensters, sondern dieses muß mittels %Key gleich 2 abgefragt werden, was sicher häufig
erwünscht ist. Auch beim Anklicken des neuen Knopfes zum Schließen in Windows 95 wird
%Key auf 2 gesetzt. Ein Standardfenster mit Dialogeigenschaften hat so z.B. den Stil $20F.
Die Stile $100 (256) und $80 (128) sind nicht mit dem neuen Stil zusammen zu verwenden.
Der Stil $200 ist dann zu verwenden, wenn ein Programm auf dem Hauptfenster
Dialogelemente anlegt.
HINWEIS: Unter Windows 95 sind nicht alle Kombinationen wirkungsvoll: Verkleinerungsund Vergrößerungsbox werden nur dann angezeigt, wenn auch ein Systemmenü vorhanden
ist.
(Der Befehl existiert nur in der Vollversion!)
WindowTitle S
S : String
Die Überschrift des Programmfensters wird festgelegt. Beispiel:
WindowTitle "Mein erstes Programm"
Wenn im Programm keine Überschrift festgelegt wird, wird eine voreingestellte Überschrift
benutzt. (Der Befehl existiert nur in der Vollversion!)
Seite 316
RGH-PROFAN²
WinCopy W
W: Integer - Handle des zu druckenden Fensters
Das Fenster mit dem Handle W wird komplett und größtmöglich auf den Drucker gegeben.
Mit WINCOPY %DESKTOP läß sich also problemlos der komplette Bildschirm drucken,
während z.B. WINCOPY %HWND das Fenster des aktuellen PROFAN²-Programmes druckt.
Im Gegensatz zu SCREENCOPY, das nur den inneren Bereich des Fensters ohne Rahmen
und Menü druckt, wird dabei das komplette Fenster gedruckt. Jedes Fenster, dessen Handle
bekannt kann somit auf den Drucker gegeben werden.
WinHelp S1,S2
S1: String - Name der Hilfedatei (mit Endung)
S2: String - Suchwort
Die Windowshilfe wird mit der Datei S1 aufgerufen. S1 muß die Endung der Hilfedatei (meißt
"HLP") enthalten und darf auch eine Pfadangabe haben. Der zweite Parameter bezeichnet
das Schlüsselwort des Hilfeabschnittes der angezeigt werden soll. So ist kontext-sensitive
Hilfe möglich.
Ist S2 ein Leerstring, wird die Hilfe mit dem Suchfenster gestartet!
Ist S2 ein Fragezeichen ("?") wird die Hilfe zur Hilfe angezeigt und bei einem Stern ("*") wird
der Inhalt der Hilfedatei angezeigt.
Word V,A=N
V: Bereichsvariable (muß mit DECLARE deklariert sein)
A: Integer - Adresse in der Bereichsvatiablen
N: Integer - Wert (0 .. 65535)
Das Word (16-Bit-Wert = 2 Byte) an der Adresse (Offset) A im Speicherbereich V wird auf
den Wert N gesetzt. Liegt A außerhalb des mit DIM zugewiesenen Speichers, erfolgt eine
Fehlermeldung.
HINWEIS: Da zwei Byte geschrieben werden, wird Adresse A und A+1 benutzt, wobei an
Adresse A das niederwertige und an Adresse A+1 das höherwertige Byte geschrieben wird.
Sollen mehere Integer in den Bereich geschrieben werden, etwa um ein Integer-Array zu
simulieren, so ist zwischen den Adressen ein Abstand von 2 einzuhalten. Beispiel:
DECLARE Bereich#
DIM Bereich#,6
WORD Bereich#,0 =1056
WORD Bereich#,2 =10251
WORD Bereich#,4 = 516
PRINT @WORD(Bereich#,0)
PRINT @WORD(Bereich#,2)
PRINT @WORD(Bereich#,4)
DISPOSE Bereich#
Seite 317
RGH-PROFAN²
WriteIni S1,S2,S3=S4
S1: String - INI-Datei (auch mit Pfad) / Registry-Klasse (32 Bit)
S2: String - Anwendung/Rubrik/Abschnitt/Registry-Pfad (32 Bit)
S3: String - Eintrag/Schlüssel
S4: String - Wert des Eintrages
Ein Eintrag in einer INI-Datei wird geändert bzw. erstellt. Existiert die INI-Datei nicht, wird sie
im angegebenen bzw. im Windowsverzeichnis erstellt.
Beispiel:
In der Datei SPIEL.INI soll
"HIGHSCORE=25000" stehen:
unter
der
Rubrik
[MeinProgramm]
der
Eintrag:
LET HighScore& = 25000
WRITEINI "SPIEL.INI","MeinProgramm",\
"HIGHSCORE"=@Str$(HighScore&)
Um die WIN.INI nicht zu überlasten, sollte jedes Programm eine eigene INI-Datei anlegen.
Dateiname und Pfad sind frei wählbar.
In der 32-Bit-Version ist es zusätzlich möglich, Werte in die Registry (Registrierdatenbank)
zu schreiben. In diesem Fall muß als erster Parameter die Klasse mit "HKEY_0" bis
"HKEY_6" angegeben werden:
HKEY_CLASSES_ROOT
HKEY_CURRENT_USER
HKEY_LOCAL_MACHINE
HKEY_USERS
HKEY_PERFORMANCE_DATA
HKEY_CURRENT_CONFIG
HKEY_DYN_DATA
=
=
=
=
=
=
=
HKEY_0
HKEY_1
HKEY_2
HKEY_3
HKEY_4
HKEY_5
HKEY_6
Der zweite Parameter ist dann der komplette "Pfad" zum Eintrag. Der dritte Parameter ist der
Schlüssel (Key), der geschrieben werden soll. Ist der Pfad und/oder der Schlüssel nicht
vorhanden,m wird er angelegt. Sind Pfad und Schlüssel vorhanden, wird der entsprechende
Wert geändert. Der letzte Parameter ist der Wert, den der Schlüssel bekommen soll.
Einzelne Einträge des Pfades werden durch Backslashes (wie beim Verzeichnis)
voneinander getrennt:
Bei einem 32-Bit-Spiel könnte der Highscore etwa wie folgt gespeichert werden:
LET HighScore& = 25000
WriteIni "HKEY_1","RGH-Soft\Spiele\MeinProgramm", \
"High-Score"=@Str$(HighScore&)
Wollten wir jetz auch noch weitere Optionen speichern, könnten wir im selben Pfad einen
anderen Schlüssel verwenden, etwa für die Sound-Einstellung:
WriteIni "HKEY_1","RGH-Soft\Spiele\MeinProgramm","Sound"="EIN"
Diese Zeile würde in der 16-Bit-Version im übrigen keinen Fehler produzieren, sondern eine
INI-Datei "HKEY_1" im Windowsverzeichnis mit einem entsprechenden Eintrag erzeugen.
Das kann durchaus gewollt sein und ermöglicht es, Programme zu schreiben, die unter 32 Bit
die Registry nutzen und unter 16 Bit entsprechende INI-Dateien. Aus diesem Grund wuden
statt der langen Klassennamen auch die kurzen Versionen HKEY_0 bis HKEY_6 für die
PROFAN²-Syntax gewählt.
Seite 318
RGH-PROFAN²
ACHTUNG: Seien Sie vorsichtig beim Überschreiben bestehender Registry-Einträge!
Ebenso wie es durch Ändern von SYSTEM.INI oder WIN.INI möglich ist, Windows
weitgehend lahmzulegen, ist dies auch mit Änderungen der Registry noch viel effektiver
möglich!
Seite 319
RGH-PROFAN²
4. Wichtige Messages
In PROFAN² werden Messages (Botschaften) mit folgender Funktion versandt:
@SendMessage(N1,N2,N3,N4)
N1 ist das Handle des Fensters, das die Sendung bekommt. N2 ist die Nummer der
Botschaft, die in den folgenden Listen im hexadezimalen Format angegeben ist. N3 (Integer
in der 16-Bit-Version / LongInt bzw. Bereich in der 32-Bit-Version) und N4 (LongInt oder
Bereich) sind gegebenenfalls zu übermittelnde Parameter. Werden diese bei einer
bestimmten Message nicht gebraucht, sind sie auf 0 zu setzen.
Hinweis für 32Bit-Version:
Die folgenden Angaben wurden unter 16-Bit getestet. Der größte Teil dütfte auch unter 32-Bit
genauso funktionieren, wenn auch nicht ausgeschlossen werden kann, daß in einigen
wenigen Messages die Parameter anders bestückt werden. Im Zweifelsfall die
entsptrechende Fachliteratur konsultieren ... oder ausprobieren. Bei den Messages zu den
Dialogelementen sind außerdem die Messagenummern verschoben. Dort werden beide
Werte angegeben.
Seite 320
RGH-PROFAN²
Button-Messages
Diese Botschaften sind für alle Arten von Buttons (Knöpfen) einzusetzen; dazu zählen auch
die Radiobuttons und Checkboxen.
ACHTUNG: Diese Messages bitte nicht bei anderen Windowsobjekten einsetzen, da dort die
gleichen Botschaftsnummern eine andere Bedeutung haben!
Der erste Wert ist für die 16-Bit-Version, der zweite für die 32-Bit-Version.
bm_GetCkeck = $0400 / $00F0
ermittelt, ob ein Radiobutton oder eine Ckeckbox markiert ist oder nicht
Rückgabewert: 0 = nicht markiert; >0 = markiert
bm_GetState = $0402 / $00F2
ermittelt den Status eines Buttons
Rückgabewert: 0 = nicht gedrückt; >0 = gedrückt
bm_SetCheck = $0401 / $00F1
markiert einen Radiobutton oder eine Checkbox
N3: 0 = nicht markieren; 1 = markieren
bm_SetState = $0403 / $00F3
setzt den Status eines Buttons
N3: 0 = normal; 1 = hervorgehoben
Seite 321
RGH-PROFAN²
ComboBox-Messages
Diese Botschaften sind für alle Arten von ComboBoxen einzusetzen; dazu zählt auch die von
PROFAN unterstützte AuswahlBox. Andere ComboBox-Typen erlauben z.B. auch die
Eingabe in der obersten Zeile oder zeigen ständig beide Teile der ComboBox an: Editierfeld
und Listbox.
ACHTUNG: Diese Messages bitte nicht bei anderen Windowsobjekten einsetzen, da dort die
gleichen Botschaftsnummern eine andere Bedeutung haben!
Der erste Wert ist für die 16-Bit-Version, der zweite für die 32-Bit-Version.
cb_AddString = $0403 / $0143
Fügt einen String zur Liste einer Auswahlbox hinzu. Der String
Bereichsvariablen.
steht in
der
N4: Bereich = hinzuzufügender String
Rückgabewert: <0 = Fehler
Beispiel:
Let S$ = "Das ist ein Test!"
String V#,0 = S$
@SendMessage(W%,$0403,0,V#)
Hierbei ist W% das Handle der Auswahlbox.
cb_DeleteString = $0404 / $0144
Löscht einen String aus Liste einer Auswahlbox.
N3: Index des zu löschenden String (erster String = 0)
Rückgabewert: <0 = Fehler
cb_Dir = $0405 / $0145
Fügt eine Liste der Dateien aus dem aktuellen Verzeichnis zur Auswahlliste hinzu. Bei der
Auswahl wird das Dateiattribut (siehe unter @GetFAttr) berücksichtigt. Um zusätzlich die
Laufwerke aufzulisten, ist $4000 dem Attribut hinzuzufügen. Die Bereichsvariable enthält die
Suchmaske.
N3: Integer = Dateiattribut
N4: Bereich = Datei-Suchmaske (z.B. "*.*")
Rückgabewert: <0 = Fehler (z.B. zu wenig Platz in der Liste)
>=0 = Index des letzten Eintrages (erster Eintrag = 0)
Beispiel:
Let S$ = "*.*"
String V#,0 = S$
@SendMessage(W%,$0405,$4037,V#)
Hierbei ist W% das Handle der Auswahlbox. Um nur eine Laufwerksliste zu erzeugen, ist als
Attribut in N3 der Wert $4000 einzusetzen.
Seite 322
RGH-PROFAN²
cb_FindString = $040C / $014C
Es wird der Eintrag ermittelt, der mit dem Suchstring beginnt.
N3: Integer = Index des Eintrages vor dem die Suche beginnt;
Soll sie am Anfang beginnen, muß er -1 sein.
N4: Bereich = Suchstring
Rückgabewert: <0 = Fehler (nicht gefunden)
>=0 = Index des gesuchten Eintrages (erster Eintrag = 0)
cb_GetCount = $0406 / $0146
Anzahl der Einträge in der Liste.
Rückgabewert: Index des letzten Eintrages (erster Eintrag = 0)
cb_GetCurSel = $0407 / $0147
Index des aktuell ausgewählten Eintrages der Liste.
Rückgabewert: Index des Eintrages (erster Eintrag = 0)
cb_GetLBText = $0408 / $0148
Kopiert einen String aus der Liste in die Bereichsvariable. ACHTUNG: Das abschließende
Byte mit dem Wert 0 ist aufgrund des Rückgabewertes selbst zu setzen!
HINWEIS: Die Bereichsvariable muß ausreichgend dimensioniert sein!
N3: Integer = Index des gewünschten Eintrages
N4: Bereich = Bereich, der den String aufnehmen soll
Rückgabewert: Länge des Strings
cb_GetLBTextLen = $0409 / $0149
Ermittelt die Länge eines String aus der Liste.
N3: Integer = Index des gewünschten Eintrages
Rückgabewert: Länge des Strings
cb_ResetContent = $040B / $014B
Löscht die Liste der Auswahlbox.
cb_SetCurSel = $040E / $014E
Wählt einen Eintrag aus der Liste aus und rollt ihn in den sichtbaren Bereich.
N3: Integer = Index des gewünschten Eintrages
-1: Kein Eintrag wird ausgewählt
Seite 323
RGH-PROFAN²
cb_SelectString = $040D / $014D
Es wird der Eintrag ermittelt, der mit dem Suchstring beginnt. Der Eintrag wird markiert und
in den sichtbaren Bereich der Liste gerollt.
N3: Integer = Index des Eintrages vor dem die Suche beginnt;
Soll sie am Anfang beginnen, muß er -1 sein.
N4: Bereich = Suchstring
Rückgabewert: <0 = Fehler (nicht gefunden)
>=0 = Index des gesuchten Eintrages (erster Eintrag = 0)
cb_ShowDropDown = $040F / $014F
Zeigt die Auswahlliste eines Auswahlfensters.
N3: 1 = Auswahlliste zeigen; 0 = Auswahlliste schließen
Seite 324
RGH-PROFAN²
Edit-Messages
Diese Botschaften sind für alle Arten von Editierfeldern einzusetzen.
ACHTUNG: Diese Messages bitte nicht bei anderen Windowsobjekten einsetzen, da dort die
gleichen Botschaftsnummern eine andere Bedeutung haben!
Der erste Wert ist für die 16-Bit-Version, der zweite für die 32-Bit-Version.
em_CanUndo = $0416 / $00C6
ermittelt, ob ein Editierfeld korrekt auf em_Undo reagieren kann
Rückgabewert: 0 = kann nicht reagieren; 1 = kann reagieren
em_GetModify = $0408 / $00B8
ermittelt, ob ein Editierfeld geändert wurde
Rückgabewert: Veränderungsflag
em_LimitText = $0415 / $00C5
bestimmt die maximale Anzahl von Zeichen, die ein Editierfeld aufnehmen darf
N3: Anzahl der Zeichen (0 = unbegrenzt)
Rückgabewert: 0 = Fehler aufgetreten
em_SetModify = $0409 / $00B9
setzt das Veränderungsflag
N3: Veränderungsflag
em_SetReadOnly = $041F / $00CF
setzt eine Editierfeld in den Nur-Lesen-Status
N3: 1 = Nur-Lesen; 0 = Lesen + Schreiben
em_Undo = $0417 / $00C7
macht die letze Aktion im Editierfeld rückgängig
Rückgabewert: 0 = Undo konnte nicht ausgeführt werden
Seite 325
RGH-PROFAN²
Listbox-Messages
Diese Botschaften sind für Listboxen zu verwenden.
ACHTUNG: Diese Messages bitte nicht bei anderen Windowsobjekten einsetzen, da dort die
gleichen Botschaftsnummern eine andere Bedeutung haben!
Der erste Wert ist für die 16-Bit-Version, der zweite für die 32-Bit-Version.
lb_AddString = $0401 / $0180
Fügt einen String zur Liste einer Listbox hinzu. Der String steht in der Bereichsvariablen.
N4: Bereich = hinzuzufügender String
Rückgabewert: <0 = Fehler
Beispiel:
Let S$ = "Das ist ein Test!"
String V#,0 = S$
@SendMessage(W%,$0401,0,V#)
Hierbei ist W% das Handle der Listbox.
lb_DeleteString = $0403 / $0182
Löscht einen String aus Liste einer Listbox.
N3: Index des zu löschenden String (erster String = 0)
Rückgabewert: <0 = Fehler
lb_Dir = $040E / $018D
Fügt eine Liste der Dateien aus dem aktuellen Verzeichnis zur Liste hinzu. Bei der Auswahl
wird das Dateiattribut (siehe unter @GetFAttr) berücksichtigt. Um zusätzlich die Laufwerke
aufzulisten, ist $4000 dem Attribut hinzuzufügen. Die Bereichsvariable enthält die
Suchmaske.
N3: Integer = Dateiattribut
N4: Bereich = Datei-Suchmaske (z.B. "*.*")
Rückgabewert: <0 = Fehler (z.B. zu wenig Platz in der Liste)
>=0 = Index des letzten Eintrages (erster Eintrag = 0)
Beispiel:
Let S$ = "*.*"
String V#,0 = S$
@SendMessage(W%,$040E,$4037,V#)
Hierbei ist W% das Handle der Listbox. Um nur eine Laufwerksliste zu erzeugen, ist als
Attribut in N3 der Wert $4000 einzusetzen.
Seite 326
RGH-PROFAN²
lb_FindString = $0410 / $018F
Es wird der Eintrag ermittelt, der mit dem Suchstring beginnt.
N3: Integer = Index des Eintrages vor dem die Suche beginnt;
Soll sie am Anfang beginnen, muß er -1 sein.
N4: Bereich = Suchstring
Rückgabewert: <0 = Fehler (nicht gefunden)
>=0 = Index des gesuchten Eintrages (erster Eintrag = 0)
lb_GetCount = $040C / $018B
Anzahl der Einträge in der Liste.
Rückgabewert: Index des letzten Eintrages (erster Eintrag = 0)
lb_GetCurSel = $0409 / $0188
Index des aktuell ausgewählten Eintrages der Liste.
Rückgabewert: Index des Eintrages (erster Eintrag = 0)
lb_GetText = $040A / $0189
Kopiert einen String aus der Liste in die Bereichsvariable. ACHTUNG: Das abschließende
Byte mit dem Wert 0 ist aufgrund des Rückgabewertes selbst zu setzen!
HINWEIS: Die Bereichsvariable muß ausreichend dimensioniert sein!
N3: Integer = Index des gewünschten Eintrages
N4: Bereich = Bereich, der den String aufnehmen soll
Rückgabewert: Länge des Strings
lb_GetTextLen = $040B / $018A
Ermittelt die Länge eines String aus der Liste.
N3: Integer = Index des gewünschten Eintrages
Rückgabewert: Länge des Strings
lb_ResetContent = $0405 / $0184
Löscht die Liste der Listbox.
Seite 327
RGH-PROFAN²
lb_SelectString = $040D / $018C
Es wird der Eintrag ermittelt, der mit dem Suchstring beginnt. Der Eintrag wird markiert und
in den sichtbaren Bereich der Liste gerollt.
N3: Integer = Index des Eintrages vor dem die Suche beginnt;
Soll sie am Anfang beginnen, muß er -1 sein.
N4: Bereich = Suchstring
Rückgabewert: <0 = Fehler (nicht gefunden)
>=0 = Index des gesuchten Eintrages (erster Eintrag = 0)
lb_SetCurSel = $0407 / $0186
Wählt einen Eintrag aus der Liste aus und rollt ihn in den sichtbaren Bereich.
N3: Integer = Index des gewünschten Eintrages
-1: Kein Eintrag wird ausgewählt
lb_SetHorizontalExtend = $0415 / $0194
Normalerweise entspricht die tatsächliche Breite einer Listbox der Breite, die am Bildschirm
zu sehen ist: Es gibt keinen horizontalen Scollbalken. Diese Message setzt die Breite der
Listboxliste in Pixel. Ist die Breite größer als der angezeigte Bereich, erhält die Liste einen
horizontalen Scrollbalken.
N3: Integer = Breite der Liste in Pixel
Seite 328
RGH-PROFAN²
Allgemeine Windows-Botschaften (Nummern gelten für 16 und 32 Bit)
wm_Clear = $0303
löscht die aktuelle Auswahl in einem Fenster
wm_Close = $0010
schließt das betreffende Fenster
wm_Copy = $0301
kopiert den markierten Text in die Zwischenablage
wm_Cut = $0300
kopiert den markierten Text in die Zwischenablage. Der markierte Text wird gelöscht.
wm_GetText = $000D
Ermittelt den Text eines Steuerelementes und überträgt ihn in die Bereichsvariable. Diese
muß ausreichen dimensioniert sein. ACHTUNG: Das abschließende Byte mit dem Wert 0 ist
aufgrund des Rückgabewertes selbst zu setzen!
Diese Botschaft entspricht der PROFAN²-Funktion @GETTEXT mit dem Unterschied, daß
auch Texte gelesen werden können, die länger als 255 Zeichen sind.
N3: Integer = maximal zu lesende Anzahl der Zeichen
N4: Bereich = nimmt den Text auf
Rückgabewert: Anzahl der gelesenen Zeichen
wm_GetTextLength = $000E
ermittelt die Länge des Textes im angegebenen Steuerelement
Rückgabewert: Länge des Textes in Bytes
wm_Paint = $000F
fordert das Fenster zum Neuzeichnen auf
wm_Paste = $0302
fügt Daten aus der Zwischenablage in das Fenster an der aktuellen Mauszeigerposition ein
Seite 329
RGH-PROFAN²
wm_SetFont = $0030
Setzt den Font (die Schrift) für das entsprechende Fenster bzw. Fensterelement. Auf diese
Weise können Editierfelder, Listboxen, Buttons, etc. mit einem frei wählbaren Font
ausgestattet werden. In der Systemvariablen %FONT ist das Handle zum zuletzt mit
USEFONT eingestellten Fonts enthalten.
N3: Integer = Handle des Fonts (0 = Systemfont)
N4: >0 = Element sofort neuzeichnen.
wm_SetText = $000C
Einem Fensterelement wird der in der Bereichsvariablen gespeicherte Text übergeben.
Diese Botschaft entspricht dem PROFAN²-Befehl SETTEXT mit dem Unterschied, daß auch
Texte übergeben werden können, die länger als 255 Zeichen sind.
N4: Bereich = enthält den Text
wm_Undo = $0304
macht die letzte Aktion (z.B. Cut oder Paste) wieder rückgängig
Seite 330
RGH-PROFAN²
Programmieren für Anwender
P R O F A N ² 6.0
DIE einfache Programmiersprache
für Windows 3.x und Windows 95
Anhang
Seite 331
RGH-PROFAN²
ANHANG 1: Fehlermeldungen
Folgende Fehlermeldungen und Warnungen werden vom Interpreter bzw. Compiler und
Runtime-System erzeugt:
Programm-Struktur
100 :
101 :
102 :
103 :
104 :
105 :
106 :
107 :
108 :
109 :
110 :
111 :
112 :
113 :
114 :
115 :
116 :
117 :
118 :
119 :
120 :
121 :
122 :
123 :
124 :
125 :
Systemvariable unbekannt:
Funktion unbekannt:
Befehl unbekannt:
Integer-Variable erwartet!
Dateikennung erwartet!
Tabellenkennung erwartet!
ENDIF bzw. ELSE nicht gefunden!
ENDIF nicht gefunden!
Zu tiefe WHILE-Verschachtelung!
ENDWHILE bzw. WHILE nicht gefunden!
WHILE fehlt!
GOSUB/PROC fehlt!
PROC fehlt!
Label nicht gefunden:
Zu tiefe GOSUB/PROC-Verschachtelung!
ENDPROC nicht gefunden!
"DIM%" darf nur einmal verwandt werden!
"DIM&" darf nur einmal verwandt werden!
"DIM$" darf nur einmal verwandt werden!
"DIM!" darf nur einmal verwandt werden!
STARTPRINT fehlt!
Bereichs-Variable erwartet!
Variablenbezeichner fehlerhaft:
Variablenname zu lang:
STARTPAINT fehlt!
SUBPOPUP fehlt!
Ungültige/fehlende Parameter
200 :
201 :
202 :
203 :
204 :
205 :
206 :
207 :
208 :
209 :
210 :
211 :
212 :
213 :
214 :
215 :
216 :
217 :
218 :
219 :
Ungültiger Funktionswert!
Division durch 0!
Falscher Typ für @DTOC$ !
Falscher Typ für @CTOD$ !
String-Index ist < 1 !
Substring-Nr ist < 1 !
So viele Elemente sind nicht da!
Bereichsgrenze überschritten:
Kommandozeilenparameter fehlt!
Datei nicht gefunden:
Dateinummer nicht im erlaubten Bereich!
Parameterzahl muß zwischen 0 und 12 liegen!
Zu wenig Parameter!
Funktionsargument fehlt!
Keine Zahl:
Variable nicht deklariert:
Falscher Parametertyp:
Speicher für Integer-Variablen erschöpft!
Speicher für LongInt-Variablen erschöpft!
Speicher für String-Variablen erschöpft!
Seite 332
RGH-PROFAN²
220 :
221 :
222 :
223 :
224 :
225 :
226 :
227 :
228 :
229 :
230 :
231 :
232 :
233 :
234 :
235 :
236 :
237 :
238 :
239 :
240 :
241 :
242 :
243 :
244 :
245 :
246 :
247 :
248 :
249 :
250 :
251 :
252 :
253 :
254 :
Speicher für Float-Variablen erschöpft!
Während der Druckausgabe verboten:
Box nicht innerhalb des Fensters!
Negative Fenstergröße!
ICON nicht vorhanden:
ICON nicht vorhanden! (Nur 0..4)
Fehler bei der Menüerstellung!
Zu tiefe Menüverschachtelung!
Bitmap nicht ladbar:
Bitmap konnte nicht gespeichert werden:
Cursor nicht vorhanden! (Nur 0..11)
Es sind lediglich 0 bis 9999 Elemente erlaubt!
Zu viele Elemente!
Das Element gibt es nicht!
Fehler bei der Tonerzeugung!
Drucken ist nicht möglioch!
Fehler bei der HardCopy!
Der Befehl setzt ein Fenster vorraus!
Stringende fehlt!
Speicher für Bereichs-Variablen erschöpft!
Zu wenig Speicher für Bereichs-Variable!
Bereichsvariable ist bereits DIMensioniert!
Ungültiges Fenster-Handle!
Bereichsvariable ist nicht DIMensioniert!
Der Text paßt nicht komplett in die Bereichsvariable!
Die Parameterzahl unterscheidet sich von der Parameterbeschreibung!
Ungültiger Typ in der Parameterbeschreibung!
Fehler beim Laden der DLL:
Funktion in DLL nicht vohanden:
Zwischen STARTPAINT/ENDPAINT verboten:
SETTIMER fehlt!
Der TIMER ist schon eingestellt!
Menü ist nicht ladbar:
Speicher für Array-Variablen erschöpft!
Maximal drei Dimensionen erlaubt!
IO-Fehler
300 :
301 :
302 :
303 :
304 :
305 :
Datei kann nicht gelesen werden:
Datei kann nicht erzeugt werden:
Fehler beim Lesen:
Fehler beim Schreiben:
PROF16.EXE nicht ausführbar oder fehlt!
REGISTRY:
ODBC-Fehler und Meldungen
500 :
501 :
502 :
503 :
504 :
505 :
506 :
507 :
ODBC ist nicht initialisiert!
Fehler bei der ODBC-Initialisierung!
ODBC.DLL nicht gefunden!
ODBC-Fehler
Sätze bearbeitet!
Operation erfolgreich!
Ergebnisdatei kann nicht geöffnet werden!
Zu große Ergebnismenge!
Seite 333
RGH-PROFAN²
DatenBank-Fehler
600 :
601 :
602 :
603 :
604 :
605 :
606 :
607 :
608 :
609 :
610 :
611 :
612 :
613 :
614 :
615 :
616 :
dB-Fehler:
Datei nicht gefunden
Doppelter Feldname
Ungültige Feldlänge
Ungültige Dezimalstellen
Index-Datei nicht in Ordnung
Feld nicht gefunden
Dateiname fehlerhaft
Schlüsselfeld nicht in Ordnung
Tabellennummer nicht im erlaubten Bereich!
Tabellennummer noch nicht vergeben!
Formel nicht in Ordnung
Feld beim Lesen nicht gefunden
Feldnummer beim Lesen nicht gefunden
Feld zum Schreiben nicht gefunden
Feldnummer zum Schreiben nicht gefunden
Index-Dateiname fehlerhaft:
Sonstige Fehler
900 :
901 :
902 :
903 :
904 :
905 :
906 :
Dieser Befehl ist in der Sharewareversion nicht vorhanden!
Nur 32767 bzw. 16380 Zeilen sind erlaubt!
Zeile zu lang (max. 254 Zeichen)!
INCLUDE-Datei nicht gefunden!
INCLUDE-Verschachtelung verboten!
Keine gültige PROFAN² Datei!
Programmdatei fehlerhaft!
Seite 334
RGH-PROFAN²
Anhang 2: Messages (Botschaften)
Für einige Botschaften, die für den PROFAN²-Programmierer besonders interessant sind,
gibt es im Kapitel 4 dieser Referenz und in der Online-Hilfe zu PROFAN² 4.0 eine
ausführlichere Beschreibung.
Die Parameter und Funktion der übrigen Botschaften sind der Fachliteratur
zur
Windowsprogrammierung zu entnehmen, z.B. "Das große Buch zu Turbo Pascal für
Windows" aus dem DATA-Becker-Verlag oder "Schnell-Ünbersicht Turbo Pascal für
Windows" aus dem Markt&Technik-Verlag. Da die Botschaften dort in der Regel nur mit
Ihrem Namen genannt werden, folgt hier nun eine Zuordnung der Botschafts-Nummern zu
ihren Namen.
Diese Liste erhebt keinen Anspruch auf Vollständigkeit. Besonders unter Windows 95 sind
noch einige Botschaften hinzugekommen.
Allgemeine Windows-Botschaften (Nummern gelten für 16 und 32 Bit)
$0007
$0008
$000A
$000B
$000C
$000D
$000E
$000F
$0010
$0011
$0012
$0013
$0014
$0015
$0016
$0018
$0019
$001A
$001B
$001C
$001D
$001E
$001F
$0020
$0021
$0022
$0023
$0024
$0026
$0027
$0028
$002A
$002B
$002C
$002D
$002E
$002F
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
wm_SetFocus
wm_KillFocus
wm_Enable
wm_SetRedraw
wm_SetText
wm_GetText
wm_GetTextLength
wm_Paint
wm_Close
wm_QueryEndSession
wm_Quit
wm_QueryOpen
wm_EraseBkGnd
wm_SysColorChange
wm_EndSession
wm_ShowWindow
wm_CtlColor
wm_WinIniChange
wm_DevModeChange
wm_ActivateApp
wm_FontChange
wm_TimeChange
wm_CancelMode
wm_SetCursor
wm_MouseActivate
wm_ChildActivate
wm_QueueSync
wm_GetMinMaxInfo
wm_PaintIcon
wm_IconEraseBkGnd
wm_NextDlgCtl
wm_SpoolerStatus
wm_DrawItem
wm_MeasureItem
wm_DeleteItem
wm_VKeyToItem
wm_CharToItem
Seite 335
RGH-PROFAN²
$0030
$0031
: wm_SetFont
: wm_GetFont
$0037
$0039
$0041
$0044
$0046
$0047
:
:
:
:
:
:
wm_QueryDragIcon
wm_CompareItem
wm_Compacting
wm_CommNotify
wm_WindowPosChanging
wm_WindowPosChanged
$0081
$0082
$0083
$0084
$0085
$0086
$0087
$00A0
$00A1
$00A2
$00A3
$00A4
$00A5
$00A6
$00A7
$00A8
$00A9
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
wm_NCCreate
wm_NCDestroy
wm_NCCalcSize
wm_NCHitTest
wm_NCPaint
wm_NCActivate
wm_GetDlgCode
wm_NCMouseMove
wm_NCLButtonDown
wm_NCLButtonUp
wm_NCLButtonDblClk
wm_NCRButtonDown
wm_NCRButtonUp
wm_NCRButtonDblClk
wm_NCMButtonDown
wm_NCMButtonUp
wm_NCMButtonDblClk
$0100
$0101
$0102
$0103
$0104
$0105
$0106
$0107
:
:
:
:
:
:
:
:
wm_KeyDown
wm_KeyUp
wm_Char
wm_DeadChar
wm_SysKeyDown
wm_SysKeyUp
wm_SysChar
wm_SysDeadChar
$0110
$0111
$0112
$0113
$0114
$0115
$0116
$0117
:
:
:
:
:
:
:
:
wm_InitDialog
wm_Command
wm_SysCommand
wm_Timer
wm_HScroll
wm_VScroll
wm_InitMenu
wm_InitMenuPopup
$011F
$0120
$0121
: wm_MenuSelect
: wm_MenuChar
: wm_EnterIdle
$0200
$0201
$0202
$0203
$0204
$0205
$0206
$0207
$0208
$0209
:
:
:
:
:
:
:
:
:
:
wm_MouseMove
wm_LButtonDown
wm_LButtonUp
wm_LButtonDblClk
wm_RButtonDown
wm_RButtonUp
wm_RButtonDblClk
wm_MButtonDown
wm_MButtonUp
wm_MButtonDblClk
Seite 336
RGH-PROFAN²
$0210
: wm_ParentNotify
$0220
$0221
$0222
$0223
$0224
$0225
$0226
$0227
$0228
$0229
$0230
$0233
:
:
:
:
:
:
:
:
:
:
:
:
$0300
$0301
$0302
$0303
$0304
$0305
$0306
$0307
$0308
$0309
$030A
$0305
$030D
: wm_Cut
: wm_Copy
: wm_Paste
: wm_Clear
: wm_Undo
: wm_RenderFormat
: wm_RenderAllFormats
: wm_DestroyClipboard
: wm_DrawClipboard
: wm_PaintClipboard
: wm_VScrollClipboard
: wm_SizeClipboard
: wm_ChangeCBChain
$030E
$030F
$0310
$0311
: wm_HScrollClipboard
: wm_QueryNewPalette
: wm_PaletteIsChanging
: wm_PaletteChanged
wm_MDICreate
wm_MDIDestroy
wm_MDIActivate
wm_MDIRestore
wm_MDINext
wm_MDIMaximize
wm_MDITile
wm_MDICascade
wm_MDIIconArrange
wm_MDIGetActive
wm_MDISetMenu
wm_DropFiles
Button-Messages
Diese Botschaften sind für alle Arten von Buttons (Knöpfen) einzusetzen; dazu zählen auch
die Radiobuttons und Checkboxen.
ACHTUNG: Diese Messages bitte nicht bei anderen Windowsobjekten einsetzen, da dort die
gleichen Botschaftsnummern eine andere Bedeutung haben!
Der erste Wert gilt für 16, der zweite für 32 Bit.
$0400 / $00F0
$0401 / $00F1
$0402 / $00F2
$0403 / $00F3
$0404 / $00F4
:
:
:
:
:
bm_GetCheck
bm_SetCheck
bm_GetState
bm_SetState
bm_SetStyle
Seite 337
RGH-PROFAN²
Edit-Messages
Diese Botschaften sind für alle Arten von Editierfeldern einzusetzen.
ACHTUNG: Diese Messages bitte nicht bei anderen Windowsobjekten einsetzen, da dort die
gleichen Botschaftsnummern eine andere Bedeutung haben!
Der erste Wert gilt für 16, der zweite für 32 Bit.
$0400 / $00B0
$0401 / $00B1
$0402 / $00B2
$0403 / $00B3
$0404 / $00B4
$0405 / $00B5
$0406 / $00B6
$0408 / $00B7
$0409 / $00B9
$040A / $00BA
$040B / $00BB
$040C / $00BC
$040D / $00BD
$040E / $00BE
$0411 / $00C1
$0412 / $00C2
$0413 / $00C3
$0414 / $00C4
$0415 / $00C5
$0416 / $00C6
$0417 / $00C7
$0418 / $00C8
$0419 / $00C9
$041A / $00CA
$041B / $00CB
$041C / $00CC
$041D / $00CD
$041E / $00CE
$041F / $00CF
$0420 / $00D0
$0421 / $00D1
$0422 / $00D2
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
em_GetSel
em_SetSel
em_GetRect
em_SetRect
em_SetRectNP
em_Scroll
em_LineScroll
em_GetModify
em_SetModify
em_GetLineCount
em_LineIndex
em_SetHandle
em_GetHandle
em_GetThumb
em_LineLength
em_ReplaceSel
em_SetFont
em_GetLine
em_LimitText
em_CanUndo
em_Undo
em_FmtLines
em_LineFromChar
em_SetWordBreak
em_SetTabStops
em_SetPasswordChar
em_EmptyUndoBuffer
em_GetFirstVisibleLine
em_SetReadOnly
em_SetWordBreakProc
em_GetWordBreakProc
em_GetPasswordChar
Seite 338
RGH-PROFAN²
Listbox-Messages
Diese Botschaften sind für Listboxen zu verwenden.
ACHTUNG: Diese Messages bitte nicht bei anderen Windowsobjekten einsetzen, da dort die
gleichen Botschaftsnummern eine andere Bedeutung haben!
Der erste Wert gilt für 16, der zweite für 32 Bit.
$0401 / $0180
$0402 / $0181
$0403 / $0182
$0405 / $0184
$0406 / $0185
$0407 / $0186
$0408 / $0187
$0409 / $0188
$040A / $0189
$040B / $018A
$040C / $018B
$040D / $018C
$040E / $018D
$040F / $018E
$0410 / $018F
$0411 / $0190
$0412 / $0191
$0413 / $0192
$0414 / $0193
$0415 / $0194
$0416 / $0195
$0418 / $0197
$0419 / $0198
$041A / $0199
$041B / $019A
$041C / $019B
$041F / $019E
$0420 / $019F
$0421 / $01A0
$0422 / $01A1
$0423 / $01A2
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
lb_AddString
lb_InsertString
lb_DeleteString
lb_ResetContent
lb_SetSel
lb_SetCurSel
lb_GetSel
lb_GetCurSel
lb_GetText
lb_GetTextLen
lb_GetCount
lb_SelectString
lb_Dir
lb_GetTopIndex
lb_FindString
lb_GetSelCount
lb_GetSelItems
lb_SetTabStops
lb_GetHorizontalExtent
lb_SetHorizontalExtent
lb_SetColumnWidth
lb_SetTopIndex
lb_GetItemRect
lb_GetItemData
lb_SetItemData
lb_SelItemRange
lb_SetCaretIndex
lb_GetCaretIndex
lb_SetItemHeight
lb_GetItemHeight
lb_FindStringExact
Seite 339
RGH-PROFAN²
ComboBox-Messages
Diese Botschaften sind für alle Arten von ComboBoxen einzusetzen; dazu zählt auch die von
PROFAN unterstützte AuswahlBox. Andere ComboBox-Typen erlauben z.B. auch die
Eingabe in der obersten Zeile oder zeigen ständig beide Teile der ComboBox an: Editierfeld
und Listbox.
ACHTUNG: Diese Messages bitte nicht bei anderen Windowsobjekten einsetzen, da dort die
gleichen Botschaftsnummern eine andere Bedeutung haben!
Der erste Wert gilt für 16, der zweite für 32 Bit.
$0400 / $0140
$0401 / $0141
$0402 / $0142
$0403 / $0143
$0404 / $0144
$0405 / $0145
$0406 / $0146
$0407 / $0147
$0408 / $0148
$0409 / $0149
$040A / $014A
$040B / $014B
$040C / $014C
$040D / $014D
$040E / $014E
$040F / $014F
$0410 / $0150
$0411 / $0151
$0412 / $0152
$0413 / $0153
$0414 / $0154
$0415 / $0155
$0416 / $0156
$0417 / $0157
$0418 / $0158
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
cb_GetEditSel
cb_LimitText
cb_SetEditSel
cb_AddString
cb_DeleteString
cb_Dir
cb_GetCount
cb_GetCurSel
cb_GetLBText
cb_GetLBTextLen
cb_InsertString
cb_ResetContent
cb_FindString
cb_SelectString
cb_SetCurSel
cb_ShowDropDown
cb_GetItemData
cb_SetItemData
cb_GetDroppedControlRect
cb_SetItemHeight
cb_GetItemHeight
cb_SetExtendedUI
cb_GetExtendedUI
cb_GetDroppedState
cb_FindStringExact
DDE-Messages (Nummern gelten für 16 und 32 Bit)
$03E0
$03E1
$03E2
$03E3
$03E4
$03E5
$03E6
$03E7
$03E8
: wm_dde_Initiate
: wm_dde_Terminate
: wm_dde_Advise
: wm_dde_Unadvise
: wm_dde_Ack
: wm_dde_Data
: wm_dde_Request
: wm_dde_Poke
: wm_dde_Execute
Seite 340
RGH-PROFAN²
ANHANG 3: Technische Daten
PROFAN² gibt es sowohl als 16- als auch als 32-Bit-Version. Hierbei wurde auf
größtmögliche Kompatibilität in beiden Richtungen gedacht. Daher ist der Befehls- und
Funktionsumfang in beiden Versionen identisch. Gerinfügige technisch bedingte
Abweichungen in der Funktion einiger weniger Befehlen und Funktionen sind in der Referenz
entsprechend vermerkt.
Aus Gründen der Kompatibilität ist in der 32-Bit-Version sogar der Aufruf von Funktionen in
16-Bit DLLs möglich, wenn PROF16.EXE ins Windowsverzeichnis kopiert wird. Wird eine 32Bit-Anwendung weitergegeben, die 16-Bit-Funktionen aufruft, muß PROF16.EXE mit
weitergegeben werden!
Das Format der PRC-Dateien (Kompilate) ist identisch, sodaß es durchaus möglich ist, das
gleiche kompilierte Programm einmal mit einer 16-Bit-Runtime und das andere Mal mit einer
32-Bit-Runtime zu starten.
32-Bit-Version von PROFAN² 6.0
32767 Programmzeilen mit je max. 255 Zeichen (PROFAN² 4.5:16380)
32767 Einträge je Array (PROFAN² 4.5: 16380)
10000 Einträge in der Listboxliste
500 Variablen je Typ (PROFAN² 4.5: 200)
max. Parameterzahl bei Prozeduren/Funktionen: 12 (PROFAN² 4.5: 8)
max. Größe Bereichsvariable: Speicher (PROFAN² 4.5: 64 kB)
While-Wend-Verschachtelung: 10
Proc-Endproc-Verschachtelung: 150 (PROFAN² 4.5: 10)
Anzahl offene Dateien: 15 (PROFAN² 4.5: 8)
Offene Datenbanktabellen: 15 (PROFAN² 4.5: 8)
Größe Datensatz: 16000 Zeichen (DBase III/PROFAN² 4.5: 4000 Zeichen)
Felder pro Satz: 1024 (DBase III/PROFAN² 4.5: 128)
16-Bit-Version von PROFAN² 6.0
16380 Programmzeilen mit je max. 255 Zeichen
16380 Einträge je Array
10000 Einträge in der Listboxliste
200 Variablen je Typ
max. Parameterzahl bei Prozeduren/Funktionen: 12 (PROFAN² 4.5: 8)
max. Größe Bereichsvariable: 64 kB
While-Wend-Verschachtelung: 10
Proc-Endproc-Verschachtelung: 50 (PROFAN² 4.5: 10)
Anzahl offene Dateien: 15 (PROFAN² 4.5: 8)
Offene Datenbanktabellen: 15 (PROFAN² 4.5: 8)
Größe Datensatz: 16000 Zeichen (DBase III/PROFAN² 4.5: 4000 Zeichen)
Felder pro Satz: 1024 (DBase III/PROFAN² 4.5: 128)
HINWEIS: Da eine Prozedur sich selbst aufrufen kann (Rekursion), gibt die Proc-EndProcVerschachtelung gleichzeitig die max. Rekursionstiefe an.
Seite 341

Similar documents