BlitzBasic - Kurs/3

von
Thomas Krippner

[Anmerkung: Thomas hat uns den Kurs zur Verfügung gestellt, ich habe inhaltlich kaum etwas geändert. Ansonsten stehen meine Kommentare in eckigen Klammern, wobei ich nur Vermutungen anstellen kann, was Blitz-Basic angeht. Red.CC]

Teil 3: Window-Programmierung

Nach der Vorschau von Teil 2 brauche ich nicht viel zu erklären, also werden wir uns mit den Windows und dessen Möglichkeiten unter BB2 beschäftigen.

Und schon gehts los:

Windows sind die mächtigsten Anzeige- und Eingabemöglichkeiten im AmigaOS. Wer systemfreundlich programmieren möchte, muß mit den Windows vertraut sein. Jeder, der mit dem Amiga arbeitet, kennt Windows und dessen Bedeutung im Umgang mit dem Amiga und der Software.

Um ein Window zu öffnen, brauchen wir einen Screen (Teil 2), dieses kann ein eigener oder ein fremder Screen sein, z.B. Workbench. Wenn wir einen Screen haben, können wir Intuition mitteilen, welcher das ist und ein Window darauf öffnen. Um mit dem Window umgehen zu können, benötigt es Gadgets, die wir mit Hilfe von Flags angeben können.

Die wichtigsten sind:

Größenveränderung, Schließen, vor- oder hinter andere Windows legen und Window verschieben usw.

Diese Flags geben wir beim Öffnen eines Windows an und können sie später nicht mehr verändern. Diese Gadgets sind System-Gadgets und keine User- Gadgets. Intuition kümmert sich ganz von alleine um dessen Ausführung, d. h. wenn eine Window Größe durch den Benutzer geändert wird, braucht unser Programm nicht die Window-Größe zu ändern, sondern muß sich nur auf die jetzige gegebene Größe einstellen.

- Öffnen eines Windows

  WBStartup

  WbToScreen 0

  Window 0,0,0,400,100,$1|$2|$4|$8|$400|$1000,"Eigenes Window",1,2

  Repeat

         FlushEvents

         ev.l=WaitEvent

  Until ev=$200

  End


In diesem Beispiel benutzen wir gleich einen fremden Screen, nämlich
den der Workbench. Doch schauen wir auf das Window.


  Window Nummer,X,Y,Breite,Höhe,Flags,Name,DPen,BPen,GTL
Nummer:
Auch unser Window braucht ein Erkennungsmerkmal

X und Y:
Linke oberste Ecke des Windows muß nicht 0 sein

Breite und Höhe:
Die Größe unseres Windows (äußerlich)

Flags des Windows:
Hier schauen Sie bitte in das BB2 - Handbuch, um die gewünschten Eigenschaften Ihrem Window zu geben.

Name:
Window-Titel

DPen und BPen:
Licht und Schattenfarben, z. B. bei Gadgets

GTL:
Die Nummer der eventuellen Gadget Liste muß nicht angegeben werden. Hierzu in Kursteil 4 mehr.

Danach schauen wir in einer Repeat-Untilschleife, ob der Benutzer ein Schließ-Gadget aktiviert und beenden das Programm sofort nach dem Benutzen. Mit der Schleife sollten Sie sich vertraut machen, denn Sie benötigen diese Struktur und die Befehle bei fast jedem Window.

Jede Aktion eines Windows wird im Event festgehalten. WaitEvent hält das Programm an, bis solch eine Aktion erfolgt. Wenn diese Aktion erfolgt ist, steht der Inhalt in der ev.l Variable und kann vom Programm abgefragt werden. Flushevents löscht die bisherigen Aktionen und bereitet Ihr Programm auf eine neue Eingabe vor.

Welche Aktion welchen Wert im WaitEvent hinterläßt steht ebenfalls im Handbuch zu Blitz Basic.

- Zwei Windows


  WBStartup

  WbToScreen 0

  Window 0,0,0,400,100,$1|$2|$4|$8|$400|$1000,"Eigenes Window",1,2
  Wi0.l=ActiveWindow

  Window 1,0,100,400,100,$1|$2|$4|$8|$400|$1000,"Eigenes Window",1,2
  Wi1.l=ActiveWindow


  Repeat

         FlushEvents

         ev.l=WaitEvent

         If Wi0 = ActiveWindow Then a=0
         If Wi1 = ActiveWindow Then a=1



         Use Window a

         NPrint "Ich bin aktiv"

  Until ev=$200

  End
In den Variablen Wi0 und Wi1 halten wir erst einmal die Adressen der gerade geöffneten und aktiven Windows fest.

Dieser Pointer vergleichen wir in der Schleife mit der Adresse des gerade aktuellen Window.

Jetzt erklären wir mit Hilfe von Use Window das Window zum aktuellen Ausgabe- und Eingabewindow, denn das aktive Window muß nicht das Ausgabe- oder Eingabe Window sein. Die Kontrolle über den Status der Windows haben wir mit den Befehlen:

Use Window - Das aktuelle Ein- und Ausgabe Window
WindowOutput - Das aktuelle Ausgaben Window
WindowInput - Das aktuelle Eingabe Window
Activate - Das aktive Window (Optische Wirkung)

Diese ist meine ganz persönliche Variante um festzustellen, welches Window aktiv ist. Es gibt auch eine BB2 Interne Variable, die meldet, von welchem Window eine Operation erfolgt ist, das wäre EventWindow.

Meine Erfahrung mit diesem Befehl ist eher negativ, denn er liefert keine brauchbaren Werte. Einen Nachteil hat natürlich auch meine Variante: Wenn Sie in den Debugger des BB2 gehen um einen Fehler oder den Programmablauf zu verfolgen, liefert der ActiveWindow-Befehl natürlich den des Debugger Window und wird deshalb nicht verzweigen. Dieses sollten Sie beachten !!!

Weiter geht es mit einem grafischem Beispiel, das in Teil 2 angekündigt wurde.

- Window auf einem Eigenen Screen


  NEWTYPE.screeninfo
         id.l
         width.l
         height.l
         _depth.w
         overscan.w
         autoscroll.w
         bmapwidth.l
         bmapheight.l
  End NEWTYPE

  NEWTYPE.WS
         _screen.l
  End NEWTYPE

  NEWTYPE.pt
         x.w
         y.w
  End NEWTYPE

  Dim p.pt(20)

  WBenchToFront_


  WbToScreen 0

  FindScreen 0

  *sc.screeninfo=ASLScreenRequest(31)

  If *sc
         Dim scrtags.TagItem(8)

         col.w=-1

         scrtags(0)\ti_Tag=#SA_Left,0
         scrtags(1)\ti_Tag=#SA_Top,0
         scrtags(2)\ti_Tag=#SA_Width,*sc\width
         scrtags(3)\ti_Tag=#SA_Height,*sc\height
         scrtags(4)\ti_Tag=#SA_Depth,*sc\_depth
         scrtags(5)\ti_Tag=#SA_Overscan,*sc\overscan
         scrtags(6)\ti_Tag=#SA_AutoScroll,*sc\autoscroll
         scrtags(7)\ti_Tag=#SA_DisplayID,*sc\id
         scrtags(8)\ti_Tag=#SA_Pens,&col

         ScreenTags 0,"BB2-Kurs von Thomas Krippner",&scrtags(0)

         Use Screen 0

         *Scr.WS=Addr Screen (0)

         Window
         0,0,11,Peek.w(*Scr\_screen+12),Peek.w(*Scr\_screen+14)-11,$1000|$400|$8,"Grafik Beispiel",1,2


         For q = 0 To 19

                p(q)\x=(InnerWidth/2)+Sin(2*q*Pi/20)*((InnerWidth/2)-1)
                p(q)\y=(InnerHeight/2)+Cos(2*q*Pi/20)*((InnerHeight/2)-1)

         Next q


         For q = 0 To 18

                For w = q+1 To 19

                 WLine p(q)\x,p(q)\y,p(w)\x,p(w)\y,1

                Next w

         Next q

         Repeat

                ev.l=WaitEvent

         Until ev = $200

  End If

  End

Die oberen NewType-Anweisungen kennen wir bereits aus Teil 2.

Neu ist der .SW den wir jetzt benutzen. Wir setzten den Pointer *Scr.SW auf die Adresse des aktuellen Screens. Dieser ist Screen 0, das haben wir in der Zeile darüber festgelegt.

Um das Window auf die Größe des vom Benutzer ausgewählten Screens zu setzten, ist es wichtig, die Größe des Screens zu kennen. Diese Größe steht in der Intuition Library hinter der Adresse des Screens. Die Adresse haben wir mit dem Befehl Addr Screen (0) auf den Pointer gelegt.

Aus der Struktur der Library (Screen) wissen wir, daß die Screenbreite unter Adresse Screen+12 steht und diese eine Wort Struktur hat. Das gleiche gilt auch für die Höhe des Screen (plus 14).

Um unser Window an diese Größe anzupassen, lesen wir die Daten mit Peek.w aus und schreiben sie in die Breite- und höheparameter des Windows.

Da wir den Titel des Screens noch sehen möchten ziehen wir noch 11 Pixel ab und setzen das Window 11 Pixel tiefer. [Die Titelzeile muß natürlich nicht genau elf Punkte hoch sein. Die tatsächliche Höhe hängt von der gewählten Schriftart ab und ist in Screen->BarHeight + 1, aber das erklärt Thomas gleich...]

Die Grafik kennen wir ebenfalls, mit dem Unterschied, daß die Größe natürlich von dem inneren Raum des Windows abhängig sein muß. BB2 kennt hierfür die InnerWidth und InnerHeight Befehle.

Der WLine Befehl ist identisch mit dem Line Befehl. Die Schleife wartet ebenfalls wieder auf das Schließgadget des Windows.

Aber was ist nun wenn der Benutzer statt einen 8 dpi einen 11 oder 6 dpi Intuifont eingestellt hat? Dieser Font bestimmt den Text in der Screen- Zeile. Wir müssen dieses Programm also noch Font-Sensitiv gestalten.

- Font-Senitiv

Dieses geht am besten mit einem Peek-Befehl.

Wir benötigen die bereits vorhandene Adresse des Screens und können von hier aus zu der Adresse des Fontnamens und der Fonthöhe springen.


  NEWTYPE.screeninfo
         id.l
         width.l
         height.l
         _depth.w
         overscan.w
         autoscroll.w
         bmapwidth.l
         bmapheight.l
  End NEWTYPE

  NEWTYPE.WS
         _screen.l
  End NEWTYPE

  NEWTYPE.pt
         x.w
         y.w
  End NEWTYPE

  Dim p.pt(20)

  WBenchToFront_


  WbToScreen 0

  FindScreen 0

  *sc.screeninfo=ASLScreenRequest(31)

  If *sc
         Dim scrtags.TagItem(8)

         col.w=-1

         scrtags(0)\ti_Tag=#SA_Left,0
         scrtags(1)\ti_Tag=#SA_Top,0
         scrtags(2)\ti_Tag=#SA_Width,*sc\width
         scrtags(3)\ti_Tag=#SA_Height,*sc\height
         scrtags(4)\ti_Tag=#SA_Depth,*sc\_depth
         scrtags(5)\ti_Tag=#SA_Overscan,*sc\overscan
         scrtags(6)\ti_Tag=#SA_AutoScroll,*sc\autoscroll
         scrtags(7)\ti_Tag=#SA_DisplayID,*sc\id
         scrtags(8)\ti_Tag=#SA_Pens,&col

         ScreenTags 0,"BB2-Kurs von Thomas Krippner",&scrtags(0)

         Use Screen 0

         *Scr.WS=Addr Screen (0)

         FH.w=Peek.w(Peek.l(*Scr\_screen+40)+4)

         Window 0,0,FH+3,Peek.w(*Scr\_screen+12),Peek.w(*Scr\_screen+14)-(FH+3), $1|$2|$1000|$400|$8,"Grafik Beispiel",1,2
         Wi0=ActiveWindow

         Gosub NeuZeichnen


         Repeat

                FlushEvents

                ev.l=WaitEvent

                If Wi0 = ActiveWindow

                 If ev=$2 Gosub NeuZeichnen

                End If

         Until ev = $200

  End If

  End

  NeuZeichnen

  WCls

  For q = 0 To 19

         p(q)\x=(InnerWidth/2)+Sin(2*q*Pi/20)*((InnerWidth/2)-1)
         p(q)\y=(InnerHeight/2)+Cos(2*q*Pi/20)*((InnerHeight/2)-1)

  Next q


  For q = 0 To 18

         For w = q+1 To 19

                WLine p(q)\x,p(q)\y,p(w)\x,p(w)\y,1

         Next w

  Next q

  Return
Nun haben wir eine Variante des Programms, mit der man leben kann.

Als erstes fällt auf, daß wir ein Label gesetzt und die Parameter des Windows verändert haben und auch die Schleife ist größer geworden.

In der FH-Variable ist die Fontgröße festgehalten. Anstatt einen festen Wert von 11 Pixel anzunehmen, benutzen wir die Fonthöhe plus den Standardabstand von 3 Pixel, oder den TopEdge der Intuition.

Dann springen wir auf Berechnung und Zeichnen der Grafik.

In der Schleife stellen wir mit $2 fest, ob eine Veränderung der Windowgröße erfolgt ist. Wenn ja, zeichnen wir die Grafik durch das Springen dorthin neu. Es ist nicht notwendig, das Window [den Rahmen] neu zu zeichnen, dieses macht Intuition automatisch, unsere Aufgabe ist es, den Inhalt des Windows anzupassen.

Das sind alle Neuerungen dieses Programms... und schon haben wir eine Window-Ausgabe und eine Umgebung, die sich auf den Benutzer einstellt.

- Window mit Bitmap

Es ist möglich, in BB2 ganze Bitmaps in ein Window zu legen. Diese Art der Window Programmierung hat mehrere Vorteile:

1.) Man braucht eine Grafik nicht immer neu zu blitten, sondern läßt sie auf der Bitmap und holt sich diese bei Bedarf in das Window.

2.) Ein anderer Vorteil ist es, die schnellen Grafikbefehle der Bitmap- programmierung zu nutzen und die Funktionsvielfalt der Windows.

Hier ein Beispiel für ein solches Programm:


 NEWTYPE.screeninfo
        id.l
        width.l
        height.l
        _depth.w
        overscan.w
        autoscroll.w
        bmapwidth.l
        bmapheight.l
 End NEWTYPE

 NEWTYPE.WS
        _screen.l
 End NEWTYPE

 NEWTYPE.pt
        x.w
        y.w
 End NEWTYPE

 Dim p.pt(20)

 WBenchToFront_


 WbToScreen 0

 FindScreen 0

 *sc.screeninfo=ASLScreenRequest(31)

 If *sc
        Dim scrtags.TagItem(8)

        col.w=-1

        scrtags(0)\ti_Tag=#SA_Left,0
        scrtags(1)\ti_Tag=#SA_Top,0
        scrtags(2)\ti_Tag=#SA_Width,*sc\width
        scrtags(3)\ti_Tag=#SA_Height,*sc\height
        scrtags(4)\ti_Tag=#SA_Depth,*sc\_depth
        scrtags(5)\ti_Tag=#SA_Overscan,*sc\overscan
        scrtags(6)\ti_Tag=#SA_AutoScroll,*sc\autoscroll
        scrtags(7)\ti_Tag=#SA_DisplayID,*sc\id
        scrtags(8)\ti_Tag=#SA_Pens,&col

        ScreenTags 0,"BB2-Kurs von Thomas Krippner",&scrtags(0)

        Use Screen 0

        *Scr.WS=Addr Screen (0)

        FH.w=Peek.w(Peek.l(*Scr\_screen+40)+4)

        Window 0,0,FH+3,Peek.w(*Scr\_screen+12),Peek.w(*Scr\_screen+14)-(FH+3) $1|$2|$1000|$400|$8,"Grafik Beispiel",1,2,0
        Wi0=ActiveWindow

        BitMap 1,Peek.w(*Scr\_screen+12),Peek.w(*Scr\_screen+14),2

        Use BitMap 1

        For q = 0 To 19

          p(q)\x=(InnerWidth/2)+Sin(2*q*Pi/20)*((InnerWidth/2)-1)
          p(q)\y=(InnerHeight/2)+Cos(2*q*Pi/20)*((InnerHeight/2)-1)

        Next q

        For q = 0 To 18

          For w = q+1 To 19

                Line p(q)\x,p(q)\y,p(w)\x,p(w)\y,1

          Next w

        Next q

        BitMaptoWindow 1,0,0,0,0,0,WindowWidth,WindowHeight

        Repeat

          FlushEvents

          ev.l=WaitEvent

          If Wi0 = ActiveWindow

                If ev=$2

                  WCls

                  BitMaptoWindow 1,0,0,0,0,0,WindowWidth,WindowHeight

                End If

          End If

        Until ev = $200

 End If

 End

[Die Sourcecodes liegen als Archiv bei.]

Im nächsten Teil der Windows Programmierung geht es dann um PropGadgets. Wir werden ein Scroll-Window erstellen und uns noch näher mit dem Peek- Befehl auseinandersetzten. Viel Spaß noch beim Experimentieren.

[Soweit der 3. Teil. Der nächste Teil folgt in der Ausgabe 7! Darin geht es dann u.a. um Windows mit Prop-Gadgets und Peek-Programmierung.]


Prev Inhaltsverzeichnis Next
©`98 Der AmZeiger