[B.Pascal 7]CRT unita a textove okna

C++, C#, Visual Basic, Delphi, Perl a ostatní

Moderátor: Moderátoři Živě.cz

Odeslat příspěvekod inflater 9. 9. 2006 09:17

Nazdar,
vratil som sa po dlhom case k programovaniu toho mojho OS v pascali.
Zase som nieco nove objavil :D (pre ostatnych nemusi byt novinka), ze ked pridam do klauzuly USES unitu CRT tak sa vsetky volania z unity CRT presmeruju rovno na BIOS a nie DOS. Tak som ziskal WriteLn a ReadLn ktore funguju uplne bez Windows a MS-DOS! (Cize ReadStr a WriteStr mozem tak pouzit v nudzovom rezime, pretoze nespolupracuju s unitou CRT :D ) Po spusteni ma samozrejme privitala Runtime Error 200 - povodna CRT nefunguje na dnesnych procesoroch; nastastie pomohol patch unity CRT od autora Pedt Scragg (na rozdiel od programu TPPATCH.EXE tato patchnuta unita spolahlivo funguje aj na mojom smejde 1,8 GHz Pentium 4).

Ale k veci:
Vyskusal som urobit spominany textovy interface (uz dajte pls pokoj s GEM a GraphicVision) s jednotkou (unit) CRT a zatial to funguje, az na male nedostatky:

1.Spravil som dajaky dialog, co skor pripomina pekelne chudobny vzhlad systemu Windows 1.x :D , ale na zaciatok si myslim, ze OK :

http://img178.imageshack.us/img178/4533/dialogqi2.jpg

Potrebujem dostat ten napis "PortixOS" nejako do stredu dialogu pomocou obycajnych suradnic, ktore sa pouzivaju pri paskalovskej CRT funkcii Window(X1,Y1,X2,Y2):

X1: suradnica X od laveho horneho rohu okna
Y1: suradnica Y od laveho horneho rohu okna
X2: suradnica X od praveho dolneho rohu okna
Y2: suradnica Y od praveho dolneho rohu okna; vid zdrojovy kod dole

Dalo by sa to aj obycajnym vycentrovanim stringu "PortixOS" tak, aby bol v strede titulkoveho pruhu, ale to by sa musel prerabat kazducky nazov titulkoveho pruhu. String v editori by vyzeral asi takto:

' PortixOS';

2. Zlozitejsi problem - oramovanie okna.

Oramovanie okna je preto, aby sa dalo rozlisit, ktore okno je hlavne a ktore jeho dialog (dalo by sa to aj farbou, ale som obmedzeny iba 7-mimi farbami). Lenze moj kod je nejaky zvlastny a poskodi titulkovy pruh okna:

http://img216.imageshack.us/img216/5301/dialog2xw2.jpg

Kod je nedokonceny kvoli tejto grafickej chybe.

Pomozete mi? :(

Tu je procedura DLGBOX, pomocou ktorej vytvaram dialogy.
Dokumentovana, ale nevycisteny zdrojovy kod.

Kód: Vybrat vše
function DlgBox(X1,Y1,X2,Y2: Byte; Caption, Text: String; Border: Boolean; HeaderColor, DlgColor, TxtColor,
TxtHdColor: Integer): Integer;
var I,J: Byte;
{X1,Y1,X2,Y2: suradnice vyssie popisane}
{Caption, Text: nadpis v tit. pruhu, text v okne}
{Border: pouzivanie ramikov TRUE/FALSE}
{HeaderColor,DlgColor:farba tit. pruhu, farba dialogu}
{TxtColor, TxtHdColor: farba textu v okne, farba textu v tit. pruhu}
begin
Window(X1,Y1,X2,Y2); {definuj suradnice okna}
TextBackground(DlgColor); {nastav pozadie okna}
ClrScr; {obnov obrazovku a nakresli okno}
GotoXY(1,1); {kurzor skoci na lavy horny roh okna}
TextBackground(HeaderColor); {nastavi farbu pozadia tit.pruhu}
TextColor(TxtHdColor);{nastavi farbu textu v pozadi v pruhu}
InsLine; {nakresli titulkovy pruh}
Writeln(Caption); {do titulkoveho pruhu napise text}
TextColor(TxtColor); {vyberie farbu obycajneho textu}
GotoXY(2,3); {skoci (v okne) tam, kde sa ide pisat text}
TextBackground(DlgColor); {vyberie farbu pozadia okna}
Writeln(Text); {napise text okna}

if Border = true then begin
{TVORBA RAMIKOV - ZACIATOK}
TextColor(White); {v titulkovom pruhu bude mat ramik bielu farbu}
TextBackground(HeaderColor); {pozadie tit. pruhu}
GotoXY(1,1);{skoci na lavy horny roh okna}
WriteLn(#218); {napise ASCII znak ramiku - roh}
GotoXY(X2 - X1 + 1, 1); {skoci na pravy horny roh okna}
WriteLn(#191); {napise ASCII znak ramiku - roh}
TextBackground(DlgColor); {nastavi pozadie ramiku}
TextColor(Black); {nastavi ciernu farbu textu}
I := 2; {modifikovana Y1 suradnica, aby sa lavy horny roh neprepisal vertikalnou ciarou}
J := Hi(WindMax) - 1; {modifikovana Y2 suradnica, aby sa vynechalo jedno miesto pre ASCII znak 0xC0 a 0xD9 (Mapa znakov, DOS)}
repeat {TU BUDE NIEKDE CHYBA}
GotoXY(X1,I);
WriteLn(#179);
Inc(I);
until I = J;
GotoXY(X1 - X2,Y2);
WriteLn(#192);
{TVORBA RAMIKOV - KONIEC}
end;
TextBackground(Black);
TextColor(White);
end;


Vopred Vam dakujem za trpezlivost.
inflater
inflater
Junior
Uživatelský avatar

Odeslat příspěvekod hekrhy 9. 9. 2006 09:57

no tak koukam na ten kod co jsi vytvoril...a nechces si to s tim programovanim systemu rozmyslet a zkusit radsi jeste neco lehciho? :) me to totiz prijde absolutne neprehledne...navic nechapu, proc kreslis tu horizontalni caru cyklem repeat-until a ne pres obycejny for? tim tam nasekas o to vic chyb...jako treba ze ten cyklus se ti opravdu ukonci o jedno driv...trochu se nad tim zamysli co to presne dela, kolik je J a kolik je I tesne pred tim nez se ukonci :wink:

Kód: Vybrat vše
GotoXY(X1 - X2,Y2);
WriteLn(#192);
mozna jsem neco prehlidl, ale tohle je podle me uplne spatne :shock:
nemelo by tam byt GoToXY(1, Y2-Y1+1)??

// EDIT:
jinak k tomu centrovani titulku okna...to jde udelat uplne jednoduse
Kód: Vybrat vše
GotoXY(((X2-X1+1)-Length(Caption)) div 2, 1)
ne? :D
hekrhy
Junior
Uživatelský avatar

Odeslat příspěvekod inflater 9. 9. 2006 12:01

Vies co, ja som zacinal v Delphi, kde je vsetko grafika (formulare), naucil som sa to a presiel som na "bezgraficky" Pascal (aj ked s Delphi stale robim), kde mi vedomosti usli :D takze s OOP nezacinam. Aj jednoduche algoritmy - napr. na riesenie mocnin. Nieco lahsieho? FTP klient, jednoduchy suborovy manazer, terminal, kalkulacka... to som vytvoril uz pekne davno v Delphi. Tak som potom vyskusal spravit OS v Assembleri - a podaril sa, ale to bol iba obycajny bootloader vobec nekompatibilny s FAT16, ale aspon cosi. S ASM programujem okrajovo (s chybami, hlavne v takzvanom Built In Assembly v Pascale) pretoze uz som precital vsetky hardcore manualy (english) a aj tak tomu nechapem :D asi je to tym vekom (13 a pol).

Najskor som ten kod (repeat-until) riesil metodou for, ale potom som skusal repeat. Uplne to iste.

Teraz k casti kodu, ktoru si oznacil ako uplne zlu:

(Sposob kreslenia vertikalnej ciary som teraz vynechal)
Ten moj sposob vynecha jednu medzeru a dopise tam ten znak (ta medzera je asi tym +1, vyskusam to odstranit.) Titulkovy pruh ostane uplne nezmeneny:

Obrázek

(Sposob kreslenia vertikalnej ciary som tiez vynechal)
Tvoj sposob sice nakresli znak rohu ramika, ale vynecha asi 6 medzier a kompletne odstrani titulkovy pruh, aj s farbami, aj s textom:

Obrázek


K tomu centrovaniu textu:
To nastastie fungovalo, diky!

inflater
inflater
Junior
Uživatelský avatar

Odeslat příspěvekod inflater 9. 9. 2006 12:14

Viete mi prosim niekto pomoct s kreslenim horizontalnej ciary? :(

//EDIT:

Aby som mal predstavu o procedure Window, tak si ju nakreslim na uhladny papier. Asi takto:

Obrázek

:D :D :lol:

inflater
inflater
Junior
Uživatelský avatar

Odeslat příspěvekod JM 9. 9. 2006 14:57

J := Hi(WindMax) - 1; {modifikovana Y2 suradnica, aby sa vynechalo jedno miesto pre ASCII znak 0xC0 a 0xD9 (Mapa znakov, DOS)}
repeat {TU BUDE NIEKDE CHYBA}
GotoXY(X1,I);
WriteLn(#179);
Inc(I);
until I = J;

Uvědom si, že WindMin a WindMax obsahují absolutní souřadnice okna na obrazovce, jenže souřadnice uvnitř okna jsou od 1,1. Za druhé WriteLn posune vždy kurzor na další řádek, na rozdíl od Write.
To všechno máš v nápovědě. Už jsi to tam určitě hledal ... nebo ne?

Takže třeba při DlgBox(10,10,49,19,...) má okno deset řádků, ale Hi(WindMax)-1 je 19, takže těch 19xWriteLn ti odskroluje obsah okna pryč.

Zkus to třeba takhle:

Kód: Vybrat vše
GoToXY(1,1);
for i := 2 to (Y2-Y1) do begin
  GoToXY(1,i);
  Write(#179);
  GoToXY(X2-X1,i);
  Write(#179);
end;


Horni ramecek:
Kód: Vybrat vše
GoToXY(1,1);
Write(#LevejHorniZnak);
for i := 2 to (X2-X1) do Write(#VodorovnejZnak);
Write(#PravejHorniZnak);
GoToXY((X2-X1+1-Length(Caption)) div 2,1);
Write(Caption);

{Ovšemže se všechno dá udělat daleko lépe než takhle pracně po jednom znaku}

Až budeš kreslit pravý dolní roh rámečku, Write tak jako tak popojede na další řádek a tím okno zas odskroluje. Takže těsně předtím nastav okno na X1,Y1,X2+1,Y2.


Mimochodem, když si zvykneš odsazovat text uvnitř bloků, bude to pro ostatní čitelnější - a možná nakonec i pro tebe. Třeba takhle.
Kód: Vybrat vše
repeat {TU BUDE NIEKDE CHYBA}
  GotoXY(X1,I);
  WriteLn(#179);
  Inc(I);
until I = J;


//edit
Neuvažoval jsi o tom, že bys mohl jako avatar používat nějaký méně sprostý obrázek?
JM
Junior
Uživatelský avatar

Odeslat příspěvekod inflater 9. 9. 2006 15:35

Hladal, ale zabudol som, ze je rozdiel Write a WriteLn (write line) :D

OK. Ten navod co si mi popisal - vyskusam a otestujem funkcnost.

Ku tomu avataru NO COMMENT.
inflater
Junior
Uživatelský avatar


Kdo je online

Uživatelé procházející toto fórum: Žádní registrovaní uživatelé a 0 návštevníků