Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht Das deutsche QBasic- und FreeBASIC-Forum
Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
 
FAQFAQ   SuchenSuchen   MitgliederlisteMitgliederliste   BenutzergruppenBenutzergruppen  RegistrierenRegistrieren
ProfilProfil   Einloggen, um private Nachrichten zu lesenEinloggen, um private Nachrichten zu lesen   LoginLogin
Zur Begleitseite des Forums / Chat / Impressum
Aktueller Forenpartner:

[gelöst] Koordinatensystem in Screen 0

 
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Allgemeine Fragen zu FreeBASIC.
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
Elektronix



Anmeldungsdatum: 29.06.2006
Beiträge: 742

BeitragVerfasst am: 04.11.2007, 16:04    Titel: [gelöst] Koordinatensystem in Screen 0 Antworten mit Zitat

Hallo, BASICer,

Ich sitze an einem Programm in Screen 0 (80*23 Zeichen). Dabei komte es mir vor, daß sich die Richtung des Koordinatensystems wärend des Programms ändert.

Ich habe eine Sub zum Zeichnen eines Fensters mit Titel und kurzem Text:


Code:

Dim MainWindow As Win
With MainWindow
   .WinStyle = "MainWindow"
   .XPos = 5
   .YPos = 4
   .Length = 61 - MainWindow.XPos 'Maximal 80
   .Hight = 15
   .Title = "Hauptfenster"
   .Text = "Dies ist das Hauptfenster"
   .Filling = Mid(Fillings, 1, 1)
   .Frame = Frame1
   .TextPosX = MainWindow.XPos + 5
   .TextPosY = MainWindow.YPos + 3
   .ForeColour = 11
   .BackColour = 9
End With
Winptr = @MainWindow


Sub DrawWin (Winptr As Win ptr)
   Color Winptr->ForeColour, Winptr->BackColour
   DrawFrame (Winptr)
   Locate Winptr->XPos , Winptr->YPos + (Winptr->Length - Len(Winptr->Title))/2-1
   Print Winptr->Title
   Locate Winptr->TextPosX, Winptr->TextPosY
   Print Winptr->Text
   
End Sub

Sub DrawFrame (Winptr As Win Ptr)
   
   Dim HeadLine As String
   Dim FootLine As String
   Dim MiddleLine As String
   Dim LineLength As Integer = Winptr->Length - 2
   Dim LineCounter As Integer 'Zählt die Anzahl der Zeile entspr. Höhe des Fensters
   
   HeadLine = Mid(Winptr->Frame, 1, 1)+ String(LineLength,(Mid(Winptr->Frame, 2, 1)))+ Mid(Winptr->Frame, 3, 1)
   FootLine = Mid(Winptr->Frame, 5, 1)+ String(LineLength,(Mid(Winptr->Frame, 2, 1)))+ Mid(Winptr->Frame, 6, 1)
   MiddleLine = Mid(Winptr->Frame, 4, 1)+ String(LineLength,Winptr->Filling)+ Mid(Winptr->Frame, 4, 1)
   
   Locate Winptr->XPos,Winptr->YPos   
   Print HeadLine
   For LineCounter = Winptr->XPos + 1 To Winptr->Hight - 1
      Locate LineCounter,Winptr->YPos
      Print MiddleLine
   Next LineCounter
   Locate Winptr->Hight, Winptr->YPos
   Print FootLine
End Sub



Das funktioniert soweit auch richtig. Aber wenn ich die X-Koordinate des Textes erhöhe, rutscht der Text nicht nach rechts, wie er sollte, sondern nach unten. Komischerweise ist die Berechnung des Position des Fenstertitels aber nach rechts ausgerichtet.

Danach steuere ich mit den Pfeiltasten den cursor-läuft auch soweit richtig- und lese bei Taste "Return" ein Wort ein (aus einem Menü). Dabei soll der Lesevorgang nur gestartet wwerden, wenn der Cursor innerhalb des Fensterrahmens (nicht AUF dem Rahmen) und sich ein Wort (bzw. Buchstabe) an der Position befindet:
Code:
Function GetTask(WinPosX As Integer, WinPosY As Integer, WinLength As Integer, WinHight As Integer) As String
   Dim Item As String = ""
   Dim X As Integer = WinPosX + 4
   Dim Y As Integer = WinPosY + 3
   Locate X ,Y , 1
   Dim Key As String
   Do
      Locate X, Y, 1
      DO
           Key = INKEY
       LOOP WHILE Key = ""
       SELECT CASE Key
         CASE CHR(255) + "K"
              IF Y > 1 THEN Y = Y - 1: 'nach links
         CASE CHR(255) + "M"
              IF Y < 80 THEN Y = Y + 1: 'nach rechts
         CASE CHR(255) + "H"
              IF X > 1 THEN X = X - 1: 'nach oben
         CASE CHR(255) + "P"
              IF X < 23 THEN X = X + 1: 'nach unten
          CASE CHR(13)                'Carriege Return
             If X > WinPosX AND Y > WinPosY And X <= WinPosX + WinHight - 1 AND Y <= WinPosY + WinLength - 2 And Screen(X,Y)<> 0 And Chr(Screen(X,Y)) <> " " Then 'Hier wird überprüft, ob der Cursor innerhalb des Fensters und auf einem Buchstaben liegt.
                
                 Item = GetItem(X, Y,WinPosX, WinPosY, WinLength, WinHight)
              Endif
       End Select
   Loop Until Key = Chr(27)           'Verlassen mit ESC
   
   Return  Item
End Function

Auch das funktioniert, mit der Ausnahme, daß GetItem auch dann gestartet wird, wenn der Cursor auf der unteren Rahmenlinie liegt. Bei den anderen Rahmenlinien oder außerhalb des Rahmens bleibt er wie gewünscht "stumm".

in der Zeile mit der Überprüfung kann ich die Abfrage der Y-Position beliebig ändern: Egal, ob
Code:
AND WinPosX + WinHight - 1

oder
Code:
AND WinPosX + WinHight - 5

ich bekomme immer das gleiche falsche Ergebnis.

Was mache ich da falsch? Warum erkennt die Überprüfung die untere Rahmenlinie nicht, und warum verschiebt sich der Text in die falsche Richtung?


Zuletzt bearbeitet von Elektronix am 05.11.2007, 22:48, insgesamt einmal bearbeitet
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
ytwinky



Anmeldungsdatum: 28.05.2005
Beiträge: 2624
Wohnort: Machteburch

BeitragVerfasst am: 04.11.2007, 22:34    Titel: Antworten mit Zitat

Hi,
Screen 0 ist der Textmodus, d.h. die 'Koordinaten' gehen in deinem Fall von:
x-Richtung 1..80
y-Richtung 1..23
Dabei hat die Ecke oben-links die Koordinaten 1, 1
Wenn du das 'Gefühl' hast, daß das Koordinatensystem im Programmverlauf gedreht wird,
hast du mglw. irgendwo mal die Parameter vertauscht oder so..
..der komplette Quelltext könnte hier Wunder wirken..
ähm, nicht hier, poste ihn einfach auf http://www.freebasic-portal.de/ in fb:porticula NoPaste
Deine (durchaus ausführlichen) Erkärungen beschreiben nur, was du möchtest,
nicht, was dein Programm macht..
Gruß
ytwinky
_________________
v1ctor hat Folgendes geschrieben:
Yeah, i like INPUT$(n) as much as PRINT USING..
..also ungefähr so, wie ich GOTO..
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
Elektronix



Anmeldungsdatum: 29.06.2006
Beiträge: 742

BeitragVerfasst am: 05.11.2007, 10:15    Titel: Antworten mit Zitat

Ok, habe es hier mal hochgeladen:

http://www.freebasic-portal.de/index.php?s=fbporticula&mode=show&id=252

Die Überprüfung der Cursorposition auf der unteren Rahmenlinie liegt in Sub "GetTask()"
Mir fällt auch auf, daß die Längenberechnung mit WinPosX + WinHight das richtige Ergebnis liefert (Höhenberechnung mit WinPosY + WinLength auch richtig), obwohl die Breite des Fensters durch WinLength festgelegt wird. Ich kann aber nicht erkennen, daß ich im Funktionsaufruf die Parameter vertauscht habe.

Der Text, der sich in die falsche Richtung verschiebt, wird in der Sub "DrawWin()" eingesetzt. Die Positionierung des Fenstertitels (in der gleichen Sub) läuft mit WinLength richtig, obwohl WinLength eigentlich die Fensterbreite (Also X-Richtung) bezeichnet..
Eine ähnliche Merkwürdigkeit habe ich auch in Sub "DrawFrame()" entdeckt. Der LineCounter sollte zwar die Höhe des Rahmens abzählen (anhand der Zeilenzahl), bezieht sich aber merkwürdigerweise auf die X-Achse.

Die Positionierung des Menüs mit WinLength läuft richtig. verwundert
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Elektronix



Anmeldungsdatum: 29.06.2006
Beiträge: 742

BeitragVerfasst am: 05.11.2007, 16:57    Titel: Antworten mit Zitat

Könnte es sein, daß in Screen0 von FreeBasic die X-Achse senkrecht und die Y-Achse waagerecht ausgerichtet sind? So kommt mir das nämlich vor.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
volta



Anmeldungsdatum: 04.05.2005
Beiträge: 1876
Wohnort: D59192

BeitragVerfasst am: 05.11.2007, 17:27    Titel: Antworten mit Zitat

lässt sich einfach testen:
Code:
Screen 0
Locate 5,14
?"a=";
?Screen(5,14)

Sleep
und siehe: ist alles normal, x-Zeile, y-Spalte
_________________
Warnung an Choleriker:
Dieser Beitrag kann Spuren von Ironie & Sarkasmus enthalten.
Zu Risiken & Nebenwirkungen fragen Sie Ihren Therapeuten oder Psychiater.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
Elektronix



Anmeldungsdatum: 29.06.2006
Beiträge: 742

BeitragVerfasst am: 05.11.2007, 17:41    Titel: Antworten mit Zitat

Ich habe aber genau ein anderes Ergebnis, zumindest in meinem Programm:

Locate X+1, Y ergibt, daß die Schrift bzw. das Fenster nach UNTEN verschoben wird (also in eigentlicher Y-Richtung). Demnah sind X-und Y-Achse vertauscht.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Digga



Anmeldungsdatum: 07.01.2006
Beiträge: 48

BeitragVerfasst am: 05.11.2007, 17:58    Titel: Antworten mit Zitat

Weiss zwar nicht, ob das hier rein passt, aber hatte auch schon verschiedene Farben
beim selben Farbcode
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
ytwinky



Anmeldungsdatum: 28.05.2005
Beiträge: 2624
Wohnort: Machteburch

BeitragVerfasst am: 05.11.2007, 18:38    Titel: Antworten mit Zitat

Elektronix hat Folgendes geschrieben:
Ich habe aber genau ein anderes Ergebnis, zumindest in meinem Programm:

Locate X+1, Y ergibt, daß die Schrift bzw. das Fenster nach UNTEN verschoben wird (also in eigentlicher Y-Richtung). Demnah sind X-und Y-Achse vertauscht.

FB-Ref hat Folgendes geschrieben:
Syntax: LOCATE [Zeile][, Spalte][, sichtbar][, Start][, Ende]
Kann es sein, daß hier die 'Verdrehung' erfolgt? grinsen
Bei deinem Beispiel wäre:
Zeile 1..23
Spalte 1..80
[Edit]
Elektronix hat Folgendes geschrieben:
..
Const Frame1 As String = CHR(201) + CHR(205) + CHR(187) + CHR(186) + CHR(200) + CHR(188) + CHR(206) + Chr(203) + CHR(204) + Chr(202) + Chr(185)'Doppelter Rahmen
..
Imho sieht das so 'besser' aus:
Code:
..
Const Frame1 As String=!"\201\205\187\186\200\188\206\203\204\202\185" 'Doppelter Rahmen
..
..aber vllt bin ich einfach nur zu faul für C&P lachen
Code:
..
Const Frame1 As String=Chr(201, 205, 187, 186, 200, 188, 206, 203, 204, 202, 185) 'Doppelter Rahmen
..
..wäre eine konservative Lösung vor lachen auf dem Boden rollen
Gruß
ytwinky
_________________
v1ctor hat Folgendes geschrieben:
Yeah, i like INPUT$(n) as much as PRINT USING..
..also ungefähr so, wie ich GOTO..
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
volta



Anmeldungsdatum: 04.05.2005
Beiträge: 1876
Wohnort: D59192

BeitragVerfasst am: 05.11.2007, 19:49    Titel: Antworten mit Zitat

Elektronix hat Folgendes geschrieben:
Ich habe aber genau ein anderes Ergebnis, zumindest in meinem Programm:

Locate X+1, Y ergibt, daß die Schrift bzw. das Fenster nach UNTEN verschoben wird (also in eigentlicher Y-Richtung). Demnah sind X-und Y-Achse vertauscht.
aber das ist doch richtig! X-Zeile , Y-Spalte !! So machst du es doch im gesamten Programm.

Aufgefallen ist mir folgendes:

MainWindow.Hight = 15; dafür ist das Hauptfenster aber recht klein nur 11 Zeilen?

In GetTask fragst du die X-Position ab, ob der Cursor noch im Hauptfenster ist X <= WinPosX + WinHight - 1 =5 + 15 - 1 =19 d.h das Hauptfenster sollte wohl bis Zeile 20 (FootLine) gehen? tut es aber nicht!
Dann liegt wohl hier ein Fehler (Sub DrawFrame):
    Locate Winptr->XPos,Winptr->YPos
    Print HeadLine
    For LineCounter = Winptr->XPos + 1 To Winptr->XPos + Winptr->Hight - 1
    Locate LineCounter,Winptr->YPos
    Print MiddleLine
    Next LineCounter
    Locate Winptr->XPos + Winptr->Hight, Winptr->YPos
    Print FootLine

_________________
Warnung an Choleriker:
Dieser Beitrag kann Spuren von Ironie & Sarkasmus enthalten.
Zu Risiken & Nebenwirkungen fragen Sie Ihren Therapeuten oder Psychiater.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
Elektronix



Anmeldungsdatum: 29.06.2006
Beiträge: 742

BeitragVerfasst am: 05.11.2007, 22:26    Titel: Antworten mit Zitat

ytwinky hat Folgendes geschrieben:
Elektronix hat Folgendes geschrieben:
..
Const Frame1 As String = CHR(201) + CHR(205) + CHR(187) + CHR(186) + CHR(200) + CHR(188) + CHR(206) + Chr(203) + CHR(204) + Chr(202) + Chr(185)'Doppelter Rahmen
..
Imho sieht das so 'besser' aus:
Code:
..
Const Frame1 As String=!"\201\205\187\186\200\188\206\203\204\202\185" 'Doppelter Rahmen
..
..aber vllt bin ich einfach nur zu faul für C&P lachen
Code:
..
Const Frame1 As String=Chr(201, 205, 187, 186, 200, 188, 206, 203, 204, 202, 185) 'Doppelter Rahmen
..
..wäre eine konservative Lösung vor lachen auf dem Boden rollen
Gruß
ytwinky


Viele Wege führen nach Rom... happy cool

Ich glaube, mit der Koordinatenzuordnung bin ich einem alten Fehler aufgesessen: Ich habe nicht mit Zeilen und Spalten gerechnet, sondern mit graphischen Koordinaten X, Y. Ist ja auch ein Text-Screen mit dem Kopf durch die Mauer wollen Autsch! . Das Koordinatensystem ist naturgemäß anders ausgerichtet. Danke für die Tips!

@Volta: Den Berechnungsfehler werde ich mal genauer untersuchen müssen. Danke auch dafür. Melde mich wieder, wenn alles geklappt hat... zwinkern
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Elektronix



Anmeldungsdatum: 29.06.2006
Beiträge: 742

BeitragVerfasst am: 05.11.2007, 22:47    Titel: Antworten mit Zitat

Hier hab ich den Fehler:

In Sub DrawFrame:
For LineCounter = Winptr->PosX + 1 To Winptr->PosY + Winptr->Length
Locate LineCounter,Winptr->PosY
Print MiddleLine
Next LineCounter
Locate Winptr->PosX +Winptr->Length, Winptr->PosY

Danke, Volta!, Jetzt stimmt es! vor Freude klatschen
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
volta



Anmeldungsdatum: 04.05.2005
Beiträge: 1876
Wohnort: D59192

BeitragVerfasst am: 05.11.2007, 23:24    Titel: Antworten mit Zitat

???????
du verwechselst wieder X <-> Y
Code:
For LineCounter = Winptr->PosX + 1 To Winptr->PosY + Winptr->Length
LineCounter (Zeilenzähler) hat nix mit PosY und nix mit Lenght zu tun! Kopf schütteln
Code:
Locate Winptr->PosX +Winptr->Length, Winptr->PosY
Locate Winptr->PosX + (hier hat Length nix verloren!) Kopf schütteln
---------------------------------------------------------------------------------

die roten Angaben fehlten in deinem Quelltext http://www.freebasic-portal.de/index.php?s=fbporticula&mode=show&id=252
    Locate Winptr->XPos,Winptr->YPos
    Print HeadLine
    For LineCounter = Winptr->XPos + 1 To Winptr->XPos + Winptr->Hight - 1
    Locate LineCounter,Winptr->YPos
    Print MiddleLine
    Next LineCounter
    Locate Winptr->XPos + Winptr->Hight, Winptr->YPos
    Print FootLine

_________________
Warnung an Choleriker:
Dieser Beitrag kann Spuren von Ironie & Sarkasmus enthalten.
Zu Risiken & Nebenwirkungen fragen Sie Ihren Therapeuten oder Psychiater.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
Elektronix



Anmeldungsdatum: 29.06.2006
Beiträge: 742

BeitragVerfasst am: 06.11.2007, 09:52    Titel: Antworten mit Zitat

volta hat Folgendes geschrieben:
???????
du verwechselst wieder X <-> Y
Code:
For LineCounter = Winptr->PosX + 1 To Winptr->PosY + Winptr->Length


Nein, diesmal nicht. Im Zuge meiner Verbesserungsversuche habe ich die Variablenbenennung vertauscht. Außerdem war meine Code-Kopie im Post-Fenster nicht ganz vollständig. Tschulldigung..
happy

Wie auch immer: Es klappt jetzt.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Allgemeine Fragen zu FreeBASIC. Alle Zeiten sind GMT + 1 Stunde
Seite 1 von 1

 
Gehe zu:  
Du kannst keine Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum nicht antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.

 Impressum :: Datenschutz