[1] [2] [3] [4] [5]

3. Init der Framework-Manager-Loaderklasse über Methoden der Manager-Basisklasse:

Eigentlich sind wir zum jetzigen Zeitpunkt nur eine Zeile weiter als bei der Position "2. Init der Framework-Manager-Basisklasse", trotzdem fange ich hier mal mit einer neuen Zählung an, da jetzt die eigentliche Manager-Klassen-Initialisierung beginnt.

Über den Aufruf "THIS.Set()" wird die Set-Methode aufgerufen, die Standardeinstellungen vornimmt - allerdings nicht für die normalen SET-Befehl der Umgebungssteuerung. Für jeden Teilbereich wird aus einem Propertie der notwendige Wert geladen. Auf der Ebene des Frameworks werden nur allgemeine Framework-Klassen gesetzt, auf der Projektspezifischen Ebene der Manager aus PROJ_MGR.VCX sind in den Properties aber jeweils die "richtigen" Werte eingestellt. Es werden die folgenden fünf Teilbereiche für den aktuellen Manager ergänzt:

Aus der Eigenschaft "this.cAddPath" werden zusätzlich notwendige Pfadangaben geladen und zum allgemeinen Pfad mit SET PATH dazuaddiert. Der ursprüngliche Status wird in einer cOld-Eigenschaft vermerkt und beim Destroy des Objektes wieder hergestellt. Beispiel: Der Loader setzt fast alle allgemeinen Pfade z.B. auf die DBFS-Unterverzeichnisse.

Aus der Eigenschaft "this.cAddClassLib" werden zusätzlich notwendige Klassenbibliotheken geladen und mit SET CLASSLIB ADDITIVE gesetzt. Der ursprüngliche Status wird in einer cOld-Eigenschaft vermerkt und beim Destroy des Objektes wieder hergestellt. Beispiel: Der Messagemanager setzt sich die zusätzliche Klassenbibliothek FWK_MESS.VCX.

Aus der Eigenschaft "this.cAddProcedure" werden zusätzlich notwendige Prozedur-Dateien geladen und mit SET PROCEDURE ADDITIVE gesetzt. Der ursprüngliche Status wird in einer cOld-Eigenschaft vermerkt und beim Destroy des Objektes wieder hergestellt. Beispiel: Der Loader setzt sich die zusätzliche Prozedure-Dateie "UTILITY". (Hinweis: Die Prozedurdatei CSVLIB wird demnächst nicht mehr gelade, sobald alle Aufrufe auf das Service-Objekt oString umgeleitet sind. Hier ist aber noch ein Performance-Test notwendig).

Aus der Eigenschaft "this.cAddLibrary" werden zusätzlich notwendige Libraries geladen und mit SET LIBRARY ADDITIVE gesetzt. Der ursprüngliche Status wird in einer cOld-Eigenschaft vermerkt und beim Destroy des Objektes wieder hergestellt. Beispiel: Der Servicemanager FWK_SRV_TOOLS (FWK_SRV.VCX) setzt sich die zusätzliche Library FOXTOOLS (sein einziger Existenzzweck, da es eine Wrapper-Klasse ist).

Aus der Eigenschaft "this.cAddService" werden die Klassennamen von weiteren Managern bzw. Serviceklassen geladen. Mit "lcService = alltrim( listvalue( lcAddService, lnCounter ) )" wird in einer Schleife die Liste der zusätzlichen Klassen abgearbeitet und mit "=createobject( lcService )" das jeweilige Objekt instanziiert. Der ursprüngliche Status wird hier nicht vermerkt, sondern im Destroy wird das Destroy der Manager- bzw. Serviceklassen aufgerufen, sofern diese noch vorhanden sind (Services könnten sich zwischenzeitlich selbst deinstalliert haben mangels Bedarf für Ihre Dienste). Wichtig ist dafür die Namenskonvention, da nur aufgerufen werden kann, wenn der Manager eine Public-Referenz hat, die "o" zzgl. dem Klassennamen ab _MGR_ folgend entspricht. Beispiel: Der Loader setzt sich die zusätzlichen Manager FWK_MGR_USER, FWK_MGR_VERSION, FWK_MGR_MESSAGE, FWK_MGR_REGISTRY und FWK_MGR_DATA.

Wichtiger Hinweis: Hier müßte man jetzt eigentlich sagen, "Begeben Sie sich zum Start, begeben Sie sich direkt dorthin...", da jetzt für jeden instanziierten Manager exakt die gleiche Routine abläuft wie bisher für den Loader seit "2. Init der Framework-Manager-Basisklasse". Das ist der Vorgang an welchem sich die Anwendung eigentlich selbst an den Haaren aus dem Sumpf zieht, da nach Initialisierung des Loaders plötztlich alle anderen benötigten Manager und Service-Klassen als Objekte zur Verfügung stehen. Nach Abschluß des Hochziehens aller Manager und der wiederum von diesen angeforderten Manager und Services geht es dann mit der Initialisierung des Loaders weiter:

Sonderfall Usermanager: Falls die Eigenschaft lDevelopment über die Initialisierung der Managerbasisklasse für den Usermanager gesetzt wird (z.B. durch Vorhandensein der Datei NOLOG.TMP, siehe Eigenschaft cDevelopment von PROJ_MGR_USER) wird lLoggedIn auf .T. gesetzt und mit dem Aufruf =this.set_user( this.cDefaultUser, this.cdefaultusername, "", .T. ) der in den Eigenschaften eingetragene Default-User automatisch eingeloggt. Das eigentliche Einloggen erfolgt allerdings _nicht_ im Init des Usermanagers (was eigentlich ein logischer Ort wäre), da im Loader wesentlich mehr Initialisierung notwendig ist und erst nach call_Install() aber vor call_Oneway() die Useranmeldung erfolgen kann.

Über den Aufruf der Methode "this.set_development()" wird der Schalter this.lDevelopment auf .T. gesetzt, sofern die Datei "this.cDevelopment" vorhanden ist. Dieser Schalter wird je nach Manager für andere Zwecke verwendet. Beispiel: Beim Loader ist es tatsächlich der globale Entwicklerschalter, beim Usermanager schaltet er das Login auf automatisch für Entwickler, beim Sprachmanager wird dadurch die Übersetzung abgeschaltet.

Über den Aufruf "this.dbfopen()" wird die Haupttabelle des Managers geöffnet. Die Tabelle "this.cTable" wird mit der Order "this.cOrder" geöffnet und das Öffnen in "this.lOpen" vermerkt, so daß beim Destroy über die korrespondierende Methode "DbfClose()" die Haupttabelle wieder geschlossen bzw. gemäßt "this.cOldOrder" die ursprüngliche Order wieder hergestellt werden kann.

Ergänzung: Diese Methode kann auch direkt mit Tabellenname und Order aufgerufen werden, um eine weitere Tabelle zu öffnen. Die Properties werden in diesem Falle nicht verwendet und Restaurierungsparameter müssen selbst vermerkt und an "Dbfclose" übergeben werden.

Hinweis: Der ganze Vorgang des Öffnen und Schließens von Tabellen sowie des Wechsels zwischen Tabellen soll durch das Standardobject "FWK_SELECT" ersetzt werden. In einem einzigen Propertie werden dann alle benötigten Parameter als komma-separierte Liste geführt und einfach an dieses Objekt übergeben. Eine Referenz auf dieses Objekt wird dann in enem Propertie hinterlegt und im Destroy automatisch zerstört. Dies ist aber noch nicht fertig.

Über die Methode "this.publish()" kann jeder Manager eine öffentliche Selbstreferenz und/oder eine Referenz auf der zugrundeliegenden Form anlegen lassen:

Ein in "this.cPublicName" gespeicherte Name wird über PUBLIC als globale Variable angelegt und "THIS" dorthinein gespeichert. Alle anderen Objekte können jetzt dieses Objekt direkt ansprechen. Beim RELEASE der Public-Variable wird dieses Objekt nicht zerstört.

Ein in "this.cPropertyName" hinterlegter Name einer Eigenschaft der Form, auf welcher das Objekt ggf. plaziert ist, wird verwendet, um in diese Eigenschaft ebenfalls ein "THIS" als Referenz zu hinterlegen. Dies findet z.B. Verwendung beim FWK_MGR_NAVIGATOR, welcher die Navigation über Menü/Toolbars in Stammdatenmasken steuert und global über diese Eigenschaft der Maske angesteuert werden kann. Im Destroy eines Objektes wird automatisch die korrespondierende Funktion "this.UnPublish" aufgerufen und alle Objektreferenzen werden wieder entfernt (was vorher nicht ganz der Fall war und extrem störende Nebeneffekte aufweisen kann, z.B. Nicht-Wiederfreigabe von Masken, welche dann als unsichtbare Restobjekte vorhanden sind und ggf. das saubere Beenden der Anwendung verhindern).

Beispiel: Menü oder Toolbar können mit "_screen.activeform.oData.Next()" auf den nächsten Satz gehen, ein Button auf der Maske würde stattdessen "thisform.oData.Next()" verwenden. Die Buttonklasse kann aber zwischen beiden Vorgehensweisen von alleine unterscheiden, so daß nur der Name der Eigenschaft und die gewünschte Methode in einem Propertie des Buttons hinterlegt werden muß (cClickAction - siehe Dokumentation FWK_BASE.DOC).

Hinweis: Das Publizieren sollte ursprünglich vor dem eigentlichen Set-Aufruf erfolgen, damit nachfolgend instanziierte Manager und Servies auf das aktuell instanziierte Objekt zugreifen könnten. Da ist aber das Konzept noch nicht ganz zu Ende gedacht gewesen, da hier ja das Objekt sein Init noch nicht abgeschlossen hat und dadurch eigentlich noch gar nicht existiert...

Services führen eine Liste der sie verwendenden Objekte. Sofern sie von keinem anderen Objekt mehr benötigt werden, können sie sich selbst aus dem Speicher entfernen, um Resourcen freizugeben. Sofern die Eigenschaft "this.nRegisterCounter" den Wert "0" statt dem Defaultwert " .NULL." hat, registrieren sie sich allerdings gleich selbst mit der Methode "this.register()".

Die Methode "Register" führt in dem Array "this.aObjects" eine Liste. Verzeichnet werden dort Objektreferenzen auf die Anwender "this.aObjects( lnLine, 1 ) = oTHIS" sowie deren eindeutige Kennung "this.aObjects( lnLine, 2 ) = oTHIS.cUniqueID", zwecks Wiederauffindung ohne die Verwendung von COMPOBJ() (siehe "2.2.1. Zuweisung einer eindeutigen Kennung").

4. Eigentliches Init der Loader-Klasse:

Jetzt sind wir wiederum in der zweiten Zeile des Inits der eigentlichen Framework-Loader-Klasse, die erste Zeile war das DoDefault() welches alle bisherigen Ereignisse ausgelöst hat.

Mit der Methode "this.set_onshutdown()" wird die vorhandene "ON SHUTDOWN"-Routine gesichert und eine neue Routine gesetzt, die beim Verwenden des Closers wahlweise den Loader beendet (sofern noch vorhanden) oder direkt auf "oBASE.QUIT()" geht, um ein ggf. noch vorhandenes Superbasisklassenobjekt zu beseitigen, welches dann versucht, die Applikaton mit Gewalt zu Beenden.

Mit der Methode "this.hideVFPtoolbars()" werden in der Entwicklungsumgebung die Werkzeuge von Visual FoxPro vom Bildschirm entfernt. Im Destroy wird mit "ShowVFPToolbars" die Umgebung des testenden Entwicklers ggf. wiederhergestellt.

Hinweis: Bisher wird noch nicht ein ggf. vorhandenes Standard-Konfigurationsprogramm für den Entwicklerarbeitsplatz aufgerufen (um z.B. den Projektpad des Menüs wieder aufzubauen).

Mit der Methode "this.set_basedir()" wird das Basisverzeichnis "this.cBaseDir" der Applikation auf "=sys(5)+curdir()" eingestellt, sofern in einer Subklasse kein anderes Verfahren ausprogrammiert wird.

Mit der Methode "this.set_specialsettings()" werden folgende besonderen Einstellungen vorgenommen:

Mit "this.lDualInterface" wird festgelegt, daß die Unterstützung für die leider etwas krisenanfälligen Dual Interfaces von ActiveX-Controls abgeschaltet werden soll.

Der Vordergrundspeicher für Visual FoxPro wird gemäß "this.nBufferSizeForeground" eingestellt, da sonst Windows NT sehr schnell mit dem Swappen anfängt, welches die Gesamtperformance der Applikation erheblich beeinträchtigen kann. (Hinweis: Aufgrund der vorliegenden marginalen Hauptspeicherausstattung von nur 32 MB bei Verwendung von NT muß der Defaultwert wohl runtergesetzt werden - die Arbeitsplätze swappen ja schon beim Öffnen und Bewegen von mehreren Fenstern...).

Der Hintergrundspeicher für Visual FoxPro wird gemäß "this.nBufferSizeBackground", um Platz für andere aktive Applikationen zu schaffen. (Hinweis: Auch hier muß man wohl runtersetzen).

Mit der Methode "this.set_systemsettings()" werden SET-Einstellungen hardcodiert für die Applikation gesetzt. Es gibt noch eine Sondermethode für das Setzen von anderen Werten falls "this.lDevelopment" gesetzt ist:

Mit der Methode "this.set_development()" sollen Einstellungen für Entwickler gesetzt werden. Derzeit wird hier nur eine Debugger-Klasse instanziiert, welche in der Eigenschaft "this.cDebugClass" vorgegeben werden kann. Diese Debugger-Klasse setzt z.B. Tastenbelegungen und (später) das Coverage-Verhalten incl. Anzeige (siehe geplanten Vortrag von wOOdy zu Coverage-Auswertungen).

Mit der Methode "this.call_configfpw()" wird die Konfigurationsdatei "this.cConfigFile" auf Vorhandensein geprüft und bei Nichtvorhanden wird eine Default-Konfigurationsdatei angelegt und die Anwendung neu gestartet.

Mit der Methode "this.set_testing()" soll _zukünftig_ eine spezielle Auswahlfunktionalität für die Testumgebung nachgebaut werden.

Mit der Methode "this.set_mandant()" soll _zukünftig_ eine spezielle Auswahlfunktionalität für Mandanten eingebaut werden (ist aber evtl. auch innerhalb von Testing abbildbar - hier werden später dann Ideen gesucht).

Mit der Methode "this.call_install()" wird die Installationsapplikation "this.cInstallApp" (Default INSTALL.APP) gesucht und ggf. ausgeführt. Danach wird der Loader neu gestartet,

Mit der Methode "this.call_backdoor()" wird eine Datei "this.cBackdoorfile" gesucht und ggf. zeilenweise abgearbeitet, um Eigenschaften für die lokale Station umzusetzen und/oder Standort-spezifische Methoden aufzurufen.

Mit der Methode "this.set_manager()" sollen _zukünftig_ anders zu installierende Spezialmanagerklassen aufgerufen werden. Derzeit nur in Subklassen interessant.

Mit der Methode "this.set_mainwindcaption()" wird der Titel des Visual FoxPro-Fenster auf "this.cMainWindCaption" gesetzt und der Ursprungstitel vermerkt zwecks Wiederherstellung im Destroy.

Mit der Methode "this.release_form" wird ggf. die Maske "this.cSplashForm" aufgelöst, falls während des Startvorganges eine Anzeigemaske aufgerufen wurde. (Hinweis: Aufruf fehlt noch).

Mit der Methode "this.call_login()" wird die Klasse "this.cLoginApp" instanziiert oder wahlweise die entsprechende Applikation gestartet. Darüber erfolgt die Anmeldung des Benutzers wie folgt:

Mit "createobject()" wird die Loginmaske "this.cloginform" erzeugt und angezeigt. Die bisherige Login-Applikation wird nicht mehr benötigt.

Mit einem SQL-Statement wird nach dem eingegebenen Benutzernamen in der Tabelle USER gesucht. Allerdings muß der Benutzereintrag das Flag "useradm.lCorrect" gesetzt haben. Diese Logik ist derzeit noch in der Login-Maskenklasse statt im Usermanager und wird demnächst verlagert.

Mit dem Aufruf "oUser.Encrypt( thisform.txtPassword.value )" wird das Benutzerpasswort verschlüsselt und mit dem eingegebenen Passwort verglichen. Diese Logik ist derzeit noch in der Login-Maskenklasse statt im Usermanager und wird demnächst verlagert.

Bei Erfolg der Aktionen 4.15.1. bis 4.15.3. wird der Benutzer mit "oUser.set_user( lcUser, cname, cfirstname, .T. )" im Usermanager eingetraggen und das lLoggedIn-Flag von der Set_user-Funktion gesetzt. Auch dieser Vorgang soll aus der Maske in den Usermanager verlagert werden.

Nach erfolgreichem Einloggen des Benutzers wird mit der Methode "this.call_oneway()" eine z.B. per eMail nachgereichte Oneway-Applikation mit dem Namen "this.cOnewayApp" (Default ONEWAY.APP) aufgerufen und ausgeführt. Bei Fehlermeldung des Oneways wird die Applikation neu gestartet.

Sofern das Einloggen des Benutzers nicht erfolgreich war oder eine Installationsapplikation aufgerufen wurde oder ein Oneway nicht erfolgreich abgearbeitet werden konnte, wird der Loader mit "this.onshutdown( .F. )" beendet.

5. Init der projektspezifischen Manager-Loaderklasse:

Nach erfolgreichem Initialisieren der Manager-Loaderklasse wird jetzt die projektspezifische Loader-Subklasse initialisiert. Derzeit wird dort folgendes gemacht:

Hier werden jetzt zusätzliche Pfadangaben initialisiert. Dies geschieht über eine Standardmethode der Managerbasisklasse, der wahlweise Variablen, Pfadangaben oder Funktionen zum Auffinden einer Pfade enthaltenden lokalen Datei übergeben werden können:

Sofern eine globale Variable vorhanden ist, könnte ein Pfad aus ihr geladen werden.

Mit "this.set_alternatepath(getenv("USER") + ".PTH")" wird geschaut, ob es eine benutzerspezifische Datei mit der Endung "PTH" gibt, welche die lokalen Pfadangaben enthält und diese werden gesetzt.

Mit "this.set_alternatepath("c:\fwk_path.txt")" bzw. "this.set_alternatepath("c:\local\fwk_path.txt")" wird nach einer lokalen Datei "fwk_path.txt" gesucht und darin enthaltene Pfade ggf. gesetzt.

Hinweise: Im Destroy hat die anwendungsspezifische Subklasse des Loaders die entsprechenden Aufräumfunktionen für das Löschen der globalen Referenzen "release oApp, oEnv" sowie das Entfernen der derzeit noch nicht namenskonformer Manager mit "oMenu.Destroy()" und "oPrint.Destroy()". Dies wird demnächst aber Entfallen.

6. Start der eigentlichen Anwendung

Nun sind wir wieder zurück im Hauptprogramm, welche gemäß 1.3. nun die Methode "Start()" des erfolgreich instanziierten Loaders aufruft. Diese Methode läßt nun die eigentliche Anwendung wie folgt starten:

Die Maske "this.cMainform" wird aufgerufen. Diese Maske startet nunmehr wie folgt:

Da manchmal pseudo-modale Benutzeroberflächen aufrecht erhalten werden sollen, haben alle Masken die Möglichkeit, die sie aufrufende Masken unsichtbar zu machen, damit der Anwender nicht mehr auf die aufrufende Maske zurückschalten kann. Die aufrufende Maske muß dafür beim Aufruf der aktuellen Maske eine Selbstreferenz übergeben (Beispiel: "DO FORM WITH THISFORM"). Diese Referenz wird dann in der Eigenschaft "oHideForm" gespeichert und dann die aufrufende Maske mit der Zeile "thisform.oHideForm.visible = .F." versteckt. Im Destroy wird die Referenz wieder gelöscht und die aufrufende Maske wieder auf sichtbar geschaltet. (Hinweis: Erweiterung angedacht zwecks Einbau unsichtbarer Zwischenmasken bei mehreren Aufrufen, d.h. es soll zukünftig nur wieder sichtbar geschaltet werden, wenn die aufrufende Maske auch wirklich sichtbar war).

In der Eigenschaft "RunMode" vermerkt die Maske mit dem Aufruf "set_runmode( "STARTED" )" den aktuellen Status. Dies ist für den Resizer und andere Serviceklassen wichtig, damit diese nicht zum ungeeigneten Zeitpunkt aufgerufen werden.

Sofern nicht die Eigenschaft "lNoTranslation" gesetzt ist, wird über den Aufruf "thisform.SetLanguage()" die Caption der Maske übersetzt. Die Methode reicht den Aufruf an "oBase.SetLanguage" weiter welches wiederum "oLanguage.SetLanguage" aufruft und sich per "this.getliteral" den eigentlichen Text holt.

Mit der Methode "call_resizer()" wird ggf. ein Resizer "cResizerClass" auf der Maske plaziert.

Mit der Methode "call_menuman()" wird der Menumanager aufgerufen und ihm werden die Eigenschaften "cMenuString" und "nMenuLevel" zwecks Aufbau des gewünschten Menüs übergeben (siehe Menümanager von Thomas Seiler für weitere Details).

Aufruf der Init-Methode des Superbasisobjektes, siehe "2.4. Initalisierung des Loaders über das Superbasisobjekt:". Hinweis: Weitere Details zur Standardmaskenklasse finden sich in FWK_BASE.DOC.

Die Methode "this.call_readevents()" wird aufgerufen, die das eigentliche Eventhandling von Benutzeraktionen startet, sofern man sich nicht in der Entwicklungsumgebung befindet. Das eigentliche Programm läuft jetzt und der Anwender kann aus dem Menü oder aus Buttons der Hauptmaske oder ggf. aus Toolbars entsprechende Funktionen anwählen.

Anhang: Konfiguration von Visual FoxPro:

1. Optionen - Forms:

Folgende Einstellungen sollten unter Optionen - Forms eingetragen sein:
Grid Lines: Yes  
Snap to Grid: Yes
Show Position: Yes
Tab Ordering: by List
Design Area: 800*600
Form-Klasse: FWK_FORM (FWK_BASE.VCX)
Formsetklasse: FWK_FORMSET (FWK_BASE.VCX)
oder wahlweise keine/projektspezifische Maskenklassen

2. Optionen - Field-Mapping:

Folgende Fieldmappings sollten eingetragen sein:
Character fwk_textbox (fwk_base)
Character(b) fwk_textbox (fwk_base)
Currency fwk_textbox (fwk_base)
Date fwk_textbox (fwk_base)
Datetime fwk_textbox (fwk_base)
Double fwk_textbox (fwk_base)
Float fwk_textbox (fwk_base)
General fwk_oleboundcontrol (fwk_base)
Integer fwk_textbox (fwk_base)
Logical fwk_checkbox (fwk_base)
Memo fwk_editbox (fwk_base)
Memo (b) fwk_editbox (fwk_base)
Numeric fwk_textbox (fwk_base)
Multiple fwk_grid (fwk_base)
Label fwk_label (fwk_base)
Wahlweise natürlich Eintragung einer Entwickler- oder projektspezifischen Subklasse der Basisklassen.

3. Optionen - Controls - Visual Class Libraries:

Folgende Klassenbibliotheken sollten unter Controls - Class Libs eingetragen sein:
fwk_bas Basisklassen
fwk_fld Felderklassen
fwk_mgr Managerklassen
fwk_button Buttonsklassen
fwk_toolbar Toolbarklassen

4. Optionen - Controls - ActiveX-Controls:

Folgende ActiveX-Controls sollten unter Controls - ActiveX eingetragen sein:

5. Optionen - Projekte

Ggf. eine entsprechende SourceControl-Software wie MS Visual Source Safe oder kompatibel.

Anhang: Namenskonventionen

Objekte

Objekt Vorsilbe Beispiel
Checkbox chk chkReadOnly
Combobox cbo cboEnglish
Befehlsknopf cmd cmdCancel
Container cnt cntCustomerInfo
Steuerung ctl ctlMisc
Editbox edt edtComments
Form frm frmFileOpen
FormSeite fpg fpgList
FormSet frs frsCustomerInfo
Grid grd grdPrices
GridSpalte grc grcCompanyName
GridKopf grh grhLineTotal
Bild img imgIcon
Label lbl lblHelpMessage
Linie lin linVertical
Listbox lst lstPolicyCodes
OLE ole oleObject1
Optionsknopf opt optFrench
Optionsgruppe opg opgType
OutlineSteuerung otl otlViews
PageFrame pgf pgfLeft
Shape (Kreis, Quadrat, Rechteck,
abgerundetes Rechteck und abgerundetes Quadrat)
shp shpCircle
Spinner spn spnDaysShown
Textbox txt txtGetText
Timer tmr tmrAlarm
Toolbar tbr tbrEditReport

Variablen (Gültigkeitsbereich)

Gültigkeitsbereich Vorsilbe Beispiel
Public/Global g gcUserName
Private p pcState
Local l lnCounter
Parameter t tdRun
Klasse keine Customer
Konstante (#DEFINE) Großbuchstaben TRUE

Variablen (Typ)

Typ Vorsilbe Beispiel
Zeichen
c
cLastName
Numerisch
n
nRangeLo
Logisch
l
lMarried
Datum
d
dPurchased
Memo
m
mComments
General
g
gWordDoc
Währung
y
ySalary
Fließkomma
f
fResults
Double
b
bValue
Bild
p
pEmployee
DatumZeit
t
tRecorded
Objektinstanz
o
oJanitor
Array
a
aMonths

Kommentare (Programmheader)

Typ des Codes Beispiel für Kopf
Standardprogramme * Programm
* Autor
* Projekt
* Erstellt
* Copyright
*) Beschreibung
* Liste der wichtigen Änderungen

Kommentare (Funktionsheader)

Typ des Codes Beispiel für Kopf
Procedure/Function PROCEDURE Sample
* Name der Procedure
* Autor
* Datum der Erstellung
* Copyrighthinweis
*) Beschreibung der Procedure
* Liste der wichtigen Änderungen

Kommentare (im Code)

Standardkommentarzeichen Erläuterung
*-- für Pseudocode
* für in Kommentar umgewandelten Code oder für Kopfinformation
*{ für Beginn der Anmerkungen zu Änderungen und Anpassungen
*} für Ende der Anmerkungen zu Änderungen und Anpassungen
*? Für Programmierer- kommentare (z.B. Ideen für die Zukunft, Verbesserungen, Fragen oder Probleme)

[1] [2] [3] [4] [5]