 |
Das deutsche QBasic- und FreeBASIC-Forum Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
|
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
Elektronix
Anmeldungsdatum: 29.06.2006 Beiträge: 742
|
Verfasst am: 04.11.2007, 16:04 Titel: [gelöst] Koordinatensystem in Screen 0 |
|
|
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 |
|
 |
ytwinky

Anmeldungsdatum: 28.05.2005 Beiträge: 2624 Wohnort: Machteburch
|
Verfasst am: 04.11.2007, 22:34 Titel: |
|
|
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 |
|
 |
Elektronix
Anmeldungsdatum: 29.06.2006 Beiträge: 742
|
Verfasst am: 05.11.2007, 10:15 Titel: |
|
|
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.  |
|
Nach oben |
|
 |
Elektronix
Anmeldungsdatum: 29.06.2006 Beiträge: 742
|
Verfasst am: 05.11.2007, 16:57 Titel: |
|
|
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 |
|
 |
volta
Anmeldungsdatum: 04.05.2005 Beiträge: 1876 Wohnort: D59192
|
Verfasst am: 05.11.2007, 17:27 Titel: |
|
|
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 |
|
 |
Elektronix
Anmeldungsdatum: 29.06.2006 Beiträge: 742
|
Verfasst am: 05.11.2007, 17:41 Titel: |
|
|
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 |
|
 |
Digga

Anmeldungsdatum: 07.01.2006 Beiträge: 48
|
Verfasst am: 05.11.2007, 17:58 Titel: |
|
|
Weiss zwar nicht, ob das hier rein passt, aber hatte auch schon verschiedene Farben
beim selben Farbcode |
|
Nach oben |
|
 |
ytwinky

Anmeldungsdatum: 28.05.2005 Beiträge: 2624 Wohnort: Machteburch
|
Verfasst am: 05.11.2007, 18:38 Titel: |
|
|
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?
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  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
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 |
|
 |
volta
Anmeldungsdatum: 04.05.2005 Beiträge: 1876 Wohnort: D59192
|
Verfasst am: 05.11.2007, 19:49 Titel: |
|
|
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 |
|
 |
Elektronix
Anmeldungsdatum: 29.06.2006 Beiträge: 742
|
Verfasst am: 05.11.2007, 22:26 Titel: |
|
|
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  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
Gruß
ytwinky |
Viele Wege führen nach Rom...
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 . 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...  |
|
Nach oben |
|
 |
Elektronix
Anmeldungsdatum: 29.06.2006 Beiträge: 742
|
Verfasst am: 05.11.2007, 22:47 Titel: |
|
|
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!  |
|
Nach oben |
|
 |
volta
Anmeldungsdatum: 04.05.2005 Beiträge: 1876 Wohnort: D59192
|
Verfasst am: 05.11.2007, 23:24 Titel: |
|
|
???????
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!
Code: | Locate Winptr->PosX +Winptr->Length, Winptr->PosY | Locate Winptr->PosX + (hier hat Length nix verloren!)
---------------------------------------------------------------------------------
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 |
|
 |
Elektronix
Anmeldungsdatum: 29.06.2006 Beiträge: 742
|
Verfasst am: 06.11.2007, 09:52 Titel: |
|
|
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..
Wie auch immer: Es klappt jetzt. |
|
Nach oben |
|
 |
|
|
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.
|
|