Hybrid-Programme (XbpCRT)

Aus Wiki des Deutschsprachige Xbaseentwickler e. V.
Zur Navigation springen Zur Suche springen


Migration mit grafischen Elementen

Das RootCRT-Fenster ist kaum konfigurierbar und hängt von den Einstellungen von cmd.exe ab. Wo mehr Flexibilität, und sei es nur in Bezug auf die verwendeten Schriftarten, gewünscht ist, scheidet RootCRT() aus.

An dieser Stelle kommt XbpCRT() ins Spiel. XbpCRT() ist eine Mischung (Hybrid) von Konsolprogramm und Programm mit (optionalen) grafischen Elementen.

In dem Moment, wo in der XPJ-Datei einer der Schalter

GUI = YES
LINK_FLAGS = /PM:PM

verwendet wird, liefert die Funktion AppType() den Wert APPTYPE_PM zurück. Aufgrund dieses Status wird in der Standard-AppSys.prg ein XbpCRT()-Fenster erstellt und mit DEF_ROWS = 25 und DEF_COLS = 80 konfiguriert, d.h. mit den Standard-Parametern, die auch ein Clipper-Programm vorzuweisen hatte.


Standard-Konsolen-Fenster mit 25 Zeilen, 80 Spalten

Werfen wir hierzu mal einen Blick in die Standard-AppSys.prg:

#define DEF_ROWS       25
#define DEF_COLS       80
#define DEF_FONTHEIGHT 16
#define DEF_FONTWIDTH   8
...
     aSizeDesktop    := AppDesktop():currentSize()
     aPos            := { (aSizeDesktop[1]-(DEF_COLS * DEF_FONTWIDTH))  /2, ;
                          (aSizeDesktop[2]-(DEF_ROWS * DEF_FONTHEIGHT)) /2  }


Es wird die Grösse des Desktops ermittelt: AppDesktop() liefert eine Referenz auf den Desktop. Diese Referenz wird durch ein Objekt der XbpDialog()-Klasse dargestellt und unterstützt daher auch die Methode :currentSize(), die ein Array mit den Desktop-Dimensionen zurückliefert. Diese Dimension umfasst immer den gesamten Desktop und rechnet eine Taskbar nicht heraus!

DEF_COLS * DEF_FONTWIDTH entspricht einem 80 * 8 = 640 Pixel

DEF_ROWS * DEF_FONTHEIHT entspricht einem 25 * 16 = 400 Pixel

Unterstellen wir eine Desktopgrösse von 1024 * 768 Pixel ergibt sich folgende Anweisung

aPos := {(1024 - 640) / 2, (768 - 400) / 2}
aPos := {384 / 2, 368 / 2}
aPos := {192, 184}

Mit diesen Positionsangaben wird das Fenster zentriert auf dem Desktop angezeigt. Man merkt an dieser Stelle auch, dass AppSys.prg in der letzten Zeit nicht aktualisiert wurde, da es inzwischen die Funktion CenterControl() gibt, mit der das gleiche Ergebnis erzielt werden kann.

Unterstellen wir jetzt eine Auflösung von 1920 * 1200 Pixel, bleibt das Fenster immer noch 640 * 400 Pixel gross und nimmt damit ziemlich genau 1/9 der verfügbaren Fläche ein, während es bei 1024 * 768 Pixel immerhin noch 1/3 war.


Anpassung des Konsol-Programm-Fensters an die Grösse des Desktop

Der andere, denkbare Ansatz ist, ein Fenster in der maximal möglichen Grösse zu erzeugen (und natürlich jede denkbare Kombination dazwischen). In diesem Zusammenhang müssen wir erst einmal einen weiteren Blick in die Standard-AppSys.prg werfen:

oCrt := XbpCrt():New ( NIL, NIL, aPos, DEF_ROWS, DEF_COLS )
oCrt:FontWidth  := DEF_FONTWIDTH
oCrt:FontHeight := DEF_FONTHEIGHT
oCrt:title      := AppName()
oCrt:FontName   := "Alaska Crt"

Standardmässig wird der Font "Alaska Crt" verwendet, der jedoch (zumindest auf meinem Rechner) nicht unter den installierten Schriftarten gelistet ist. Wir benötigen auf jeden Fall eine Schriftart, die

  • mono-spaced (also nicht proportional) und
  • möglichst skalierbar

ist. In den vergangenen Jahren hat mir in diesem Zusammenhang die Windows-Schrift Lucida Console gute Dienste geleistet, da sie beide Bedingungen erfüllt.

Eine angepasst AppSys.prg, mit der ausgehend von der Desktop-Grösse die Grösse der Schriftart bestimmt wird, könnte so aussehen:

aSizeDesktop    := AppDesktop():currentSize()
nFontWide := Int(aSizeDesktop[1] / DEF_COLS * 0.95)
nFontHigh := Int(aSizeDesktop[2] / DEF_ROWS * 0.95)
aPos := {1, 1}
oCrt := XbpCrt():New ( NIL, NIL, aPos, DEF_ROWS, DEF_COLS )
oCrt:FontWidth  := nFontWide
oCrt:FontHeight := nFontHigh
oCrt:title      := AppName()
oCrt:titleBar   := TRUE
oCrt:FontName   := "Lucida Console"
oCrt:Create()

Die Breite eines Zeichens wird mit dieser Anweisung ermittelt (ausgehend von einem 1024 * 768 Pixel Desktop):

nFontWide := Int(aSizeDesktop[1] / DEF_COLS * 0.95)
nFontWide := Int(1024 / 80 * 0.95)
nFontWide := Int(12.8 * 0.95)
nFontWide := Int(12.16)
nFontWide := 12

Der Korrekturwert von 0.95 dient dazu, dass nicht die ganze Desktopfläche eingenommen wird, sondern maximal 95 % der Breite und 95 % der Höhe.

Diese beiden Beispiele können als Blaupause dienen, um entsprechende Berechnungen durchzuführen, damit das "klassisch" zu nennende Seitenverhältnis von 4:3 bei Clipper-Programmen auch auf Windows-Desktops mit 16:9 oder 16:10 Seitenverhältnis entsprechend darzustellen.

Es fällt auch auf, dass die Methode :new() als vierten Parameter kein Array für die Grösse des Fensters erwartet, sondern stattdessen die Anzahl Zeilen, gefolgt von der Anzahl Spalten.


Verwendung der Clipper-UI-Methoden

Auf dieses XbpCRT()-Fenster können alle klassischen Clipper-UI-Elemente angewendet werden, von @ x, y SAY abc GET cFeld über PROMPT und TBrowse.

Neben den in RootCRT-Fenster angesprochenen Punkten gibt es hier keine weiteren Beschränkungen. Aber erweiterte Möglichkeiten:


Verwendung von Xbase-Parts und grafisch-orientierten Funktionen

Eine der ersten grafisch-orientierten Funktionen ist ConfirmBox(), ein über wenige Parameter steuerbares Dialog-Element, um einfache Entscheidungen vom Benutzer abzufragen. Es findet sich unter anderem in der ErrorSys.prg. ConfirmBox() kann jedoch nur in Programmen eingesetzt werden, die mit GUI = YES bzw. LINK_FLAGS = /PM:PM erstellt wurden.

Die meisten Beispiele in der Alaska Dokumentation zu Xbase++ beruhen auf einem XbpCRT()-Fenster, auf dem Xbase-Parts platziert werden.