Tips und Tricks für Programmierer

Bei meinem Programm habe ich die Benutzeroberfläche mit einem Zeichenprogramm entworfen. Wie kann ich einen Button als gedrückt markieren?

Ein einfacher Weg besteht darin, das Rechteck, also den Button selbst, revers darzustellen. Das heißt, daß jeder gesetzte Pixel gelöscht und jeder nicht gesetzte Pixel gesetzt wird. Das nachfolgende Programm stellt ein beliebiges Rechteck revers (Button selektiert) und nach kurzer Pause wieder normal dar. (Sandro Lucifora/ah)

PROCEDURE reverse (xl%, yl%, xr%, yr%)
	GRAPHMODE 3
	DEFFILL 1, 1
	PBOX xl%, yl%, xr%, yr%
	PAUSE 2
	PBOX xl%, yl%, xr%, yr%
	GRAPHMODE 1
RETURN

Wie stelle ich ein Fadenkreuz in jeder Auflösung auf dem Bildschirm dar, ohne den Hintergrund zu zerstören?

Viele Zeichen- und CAD-Programme verwenden zum exakten Zeichnen ein Fadenkreuz, das über den gesamten Bildschirm reicht. Die horizontalen und vertikalen Hilfslinien stellen eine enorme Arbeitserleichterung dar Listing 1 erzeugt ein Fadenkreuz, das Sie z. B. in eigene Grafikanwendungen einbinden können. Das Listing definiert in der Prozedur »init_var« zunächst einige Variablen. Mit der Routine »mouse_bewegen« überprüft das Programm, ob die Maus bewegt wurde. Diese Abfrage verhindert ein Flackern des Bildschirms. Je nach Bewegungsrichtung zeichnet das Programm die x- oder y-Achse des Fadenkreuzes neu. Graphmode3 verhindert das Übermalen des Hintergrundes. (Sandro Lucifora/ah)

Listing 1: Ein Fadenkreuz als Hilfestellung beim Zeichnen

´ 09.01.1991   Sandro Lucifora für TOS
@init_var
DO					! Endlosschleife
	@mouse_bewegen
LOOP
´
PROCEDUR init_var
	HIDEM			! Mouse weg
	mxx% = 2000
	myy% = 2000
	wx% = WORK_OUT(0)	! x-Auflösung
	wy% = WORK_OUT(1)	! y-Auflösung
RETURN
´
PROCEDURE mouse_bewegen
	MOUSE mx%, my%, mk
	IF mx% <> mxx% OR my% <> myy%	! ist die Mouse bewegt?
		DEFLINE &X11111111111111111010101010101011
		GRAPHMODE 3
		IF mx% <> mxx%	! x bewegt?
			LINE mxx%, 1, mxx%, wy%
			LINE mx%, 1, mx%, wy%
		ENDIF
		IF my% <> myy%	! y bewegt?
			LINE 1, myy%, wx%, myy%
			LINE 1, my%, wx%, my%
		ENDIF
	ENDIF
	mxx% = mx%	! test-x = aktuelles x
	myy% = my%	! test-y = aktuelles y
RETURN

Ich möchte an jedem Tag, an dem ich den Computer einschalte, nicht nur das Datum auf dem Bildschirm ausgeben, sondern auch den entsprechenden Wochentag. Gibt es da einen Weg, ohne lange auf das Ergebnis zu warten?

Die Prozedur in Listing 2 liefert zum aktuellen Datum den richtigen Wochentag. Dafür nimmt die Routine den im Computer eingestellten Wert. Falls Sie über keine eingebaute Uhr verfügen, sind sinnvolle Werte nur bei neu gesetztem Datum zu erwarten, für dessen Einstellung bereits zahllose Programme im Umlauf sind. Um den richtigen Wochentag zu ermitteln, gehen wir zunächst von einem festen Datum aus. Da vergangene Tage nicht relevant sind, verwenden wir als Fix-Datum den 1.1.1991. Die Variable »tage%« definiert die Tage des aktuellen Monats. Aus der Anzahl der Tage der letzten Monate (Jahre) errechnet das Programm schließlich den korrekten Wochentag, wobei es die alle vier Jahre wiederkehrenden Schaltjahre berücksichtigt. Der Tag steht in der Rückgabevariablen »wochentag$«. (Sandro Lucifora/ah)

Listing 2: Zum aktuellen datum den richtigen Wochentag

´ 09,01.1991 von Sandro Lucifora für TOS
@wochentag (wochentag$)
´
PRINT „Es ist “; wochentag$: „, der “; DATE$
´
PROCEDURE wochentag (VAR tag$)
	LOCAL tag%, monat%, jahr%, tage%, z%, mt%
	tag%   = VAL (MID$ (DATE$, 1, 2))
	monat% = VAL (MID$ (DATE$, 4, 2))
	jahr%  = VAL (MID$ (DATE$, 7, 4))
´
´ Tage vom 01.01.1991 bis zum datum hochzaehlen
´
	tage% = tag%	! tage% + anzahl tage
´
	IF monat% > 2 AND FRAC (jahr%/4) = 0
		INC tage%
	ENDIF
´
	RESTORE mt	! tage% + tage von jede monat
	FOR z% = 1 TO SUB (Monat%, 1)
		READ mt%
		ADD tage%, mt%
	NEXT z%
´
	FOR z% = 1992 TO jahr%	! tage% + tage von jedem jahr
		ADD tage%, 365
		IF FRAC (SUB(z%, 1)/4) = O
			INC tage%	! schaltjahr
		ENDIF
	NEXT z%
´
´ aus der anzahl der tage den wochentag finden
´
	RESTORE wt%
	FOR z% = 1 TO SUB (tage%, MUL( DIV (tage%, 7),7))
		READ tag$
	NEXT z%
mt:
	DATA 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
wt:
	DATA Dienstag, Mittwoch, Donnerstag, Freitag
	DATA Samstag, Sonntag, Montag
RETURN

Ins rechte Bild gerückt

Bei der Präsentation einer Grafik erscheint diese meist unmittelbar auf dem Bildschirm. Daß es auch anders geht, zeigt Listing 3. Unsere Routine kopiert das Bild blockweise in den Bildschirm; ein leicht zu erzielender Effekt, der sich sehen lassen kann. (Sandro Lucifora/ah)

Listing 3: Bilder blockweise einblenden

´ 08.01.1991 Sandro Lucifora für TOS
´
@init_bild( „D:\TEST.PIC“)
@put_bild
PROCEDURE init_bild (bild_name$)
	LOCAL laenge
	OPEN „I“, #1, bild_name$
	laenge% = LOF(#1)
	bild$ = INPUT$ (laenge%, #1)
	CLOSE #1
´
	bild_1% = XBIOS (2) 	! bildschirmadresse
	bild_2% = V:bild$	! adresse des geladenen Bildes
´
	s_x% = WORK_OUT (O)	! x- und y-größe der
	s_y% = WORK_OUT (1)	! momentanen auflösung
RETURN
´
PROCEDURE put_bild
	LOCAL gx%, gy%
	gx% = DIV (ADD (s_x%, 1), 20)
	gy% = DIV (ADD (S_y%, 1), 20)
	DIM gitter!(SUB(gx%, 1), SUB(gy%,1))	! testgitter dimensionieren
	ARRAYFILL gitter!(), FALSE
	CLR zaehler%
´
	REPEAT
		set_x% = RAND (gx%)
		set_y% = RAND (gy%)
		IF NOT gitter! (set_x%, set_y%)
			gitter! (set_x%,set_y%) = TRUE
			MUL set_x%, 20
			MUL set_y%, 20
			RC_COPY bild_2%, set_x%, set_y%, 20, 20 TO bild_1%, set_x%, set_y%
			INC zaehler%
		ENDIF
	UNTIL zaehler% = ADD(s_x%, 1)
´
	ERASE gitter!()
	RETURN

# Vertikales Scrolling im Interrupt

Für Assembler-Programmierer interessant: Eine Scroll-Routine für die geringe ST-Auflösung, die im »Vertical Blank Interrupt« (VBL) abläuft - also völlig unabhängig vom Hauptprogramm. Der VBL-Interrupt erfolgt bei einem Farbmonitor in der Regel 50 mal pro Sekunde und signalisiert den Rücklauf des Rasterstrahls im Monitor. Bei jedem neuen VBL springt der Prozessor über den Exceptionvektor 28 unsere Routine an, die wir vorher mit der BIOS-Funktion »Setexc« eintragen.
Diese scrollt die ersten beiden Planes, also nur die Pixel, welche die ersten vier Farben der Palette enthalten, um eine Zeile nach unten. Vorteil: Die fünfte und neunte Farbe bleiben völlig unangetastet, d.h. alle Punkte, die in diesen Farben gezeichnet sind, behalten ihre Position auf dem Bildschirm bei. Dadurch entstehen interessante Effekte. Den Quelltext finden Sie auf der TOS-Diskette im Archiv »Tips«. Die Routine selbst kopiert - angefangen bei der vorletzten Bildschirmzeile - lediglich jede Zeile um einen Pixel nach unten, bis die erste erreicht ist. Wir legten besonderen Wert auf die Geschwindigkeit, da der Kopiervorgang weniger als eine 50stel Sekunde in Anspruch nehmen darf, also vor dem nächsten VBL-Interrupt seine Arbeit beenden muß. Diesbezüglich ist die Routine weitgehend optimiert. Das Hauptprogramm kümmert sich nur noch um den neuen Inhalt der ersten Bildschirmzeile, die nach jedem Durchlauf einer Erneuerung bedarf. (ah)

Wie begrenze ich die Größe meines Programms, damit ich eventuell auch noch Accessories aufrufen kann?

GFA-Basic bietet zwei verschiedene Wege, die Größe der Speicherbelegung eines Programms festzulegen. Der Befehl »RESFRVExxx« begrenzt beim Interpreter den vom Programm nutzbaren Speicher. Der Compiler-Befehl »m$xxxxx« weist das Programm dazu in, den Speicherplatzbedarf des zu compilierenden Quelltextes im angegebenen Rahmen zu halten. (Sandro Lucifora/ah)

Ich besitze GFA-Basic 3.01 und möchte ein in Version 3.06 geschriebenes Programm laden. Der Interpreter lehnt das Programm jedoch ab. Das »einMERGEn« entfällt, da im »INLINE« Informationen stehen. Gibt es einen anderen Weg, das Programm in Version 3.01 zu laden?

Ab Version 3.04 sind die gespeicherten Quelltexte im »*.GFA«-Dateiformat kürzer. Dies bedeutet, das ältere Versionen diese Dateien nicht erkennen. Abhilfe schafft das nachfolgende Listing, das den Original-Quelltext verlängert.

OPEN „A“ #1, dateiname$
PRINT STRING$(1000,0)
CLOSE #1

Sollte es beim ersten Anlauf nicht klappen, so wiederholen Sie diesen Schritt nochmal. (Sandro Lucifora/ah)

Ich möchte ein mit WIND_CREATE angemeldetes Fenster mit WIND_OPEN öffnen. Leider geht aus dem Handbuch nicht hervor, wie die Attribute korrekt übergeben werden.

Die Übergabe der Attribute erfolgt in einem Bitfeld. Wichtig: Das erste Attribut im Bitfeld ist das letzte der Liste im Handbuch. Wie kann ich die Druckereinstellungen des Kontrollfeldes auch in GFA-Basic vornehmen? Das Betriebssystem hält für diese Einstellungen eine XBIOS-Funktion (»Extended Input/Output System«) bereit. Mit

~XBIOS (33, konfig%)

stellen Sie die Druckerdaten ein. Die Tabelle zeigt Ihnen den Aufbau von »konfig%«. (Sandro Lucifora/ah)

Bit	Wert	Bedeutung
1	1	0 = Endlos	1 = Einzelblatt
2	2	0 = Parallel	1 = Seriell
3	4	0 = Draft	1 = NLQ
4	8	0 = 1280	1 = 960 Punkte pro Zeile
5	16	0 = Farbe	1 = Schwarzweiß
6	32	0 = Matrix	1 = Typenrad

Tabelle Mit diesem Bitfeld läßt sich der Drucker individuell konfigurieren Ich möchte gerne beim Öffnen einer Fileselect-Box den zuletzt gewählten Pfad vorgeben. Wo hole ich mir diese Information?

Mit der nachfolgenden Prozedur, welche Sie immer statt des Aufrufs der Fileselect-Box anspringen, halten Sie den zuletzt gewählten Pfad ein. Ab TOS-Version 1.04 enthält die Variable »text$« die Kopfzeile der Fileselect-Box. »gewaehlt$« enthält den gewünschten Pfad. (Sandro Lucifora/ah)

PROCEDURE fileselect(text$)
	FILESELECT #txt$, pfad$, „„, gewaehlt$
	IF LEN (gewaehlt$)	! wenn datei gewählt
		pfad$ = gewaehlt$
		IF RIGHT$ (pfad$) „\“	! wenn nicht nur ordner geöffnet
			pos% = RINSTR (pfad$,“\“)	! letzten backslash suchen
			pfad$ = LEFT$ (pfad$, pos%)	! dateinamen entfernen
		ENDIF
		pfad$ = pfad$ + “*.*“	! *.* anfügen
	ENDIF
RETURN


Aus: TOS 03 / 1991, Seite 89

Links

Copyright-Bestimmungen: siehe Über diese Seite