Este sitio web usa cookies de terceros para analizar el tráfico y personalizar los anuncios. Si no está de acuerdo, abandone el sitio y no siga navegando por él. ×


Curso de Pascal. Tema 17.4: Turbo Vision - Ventanas de texto.

Ya hemos visto cómo crear ventanas de diálogo, que "paralizan" al resto de la aplicación mientras estén activas.

Ahora veremos cómo crear ventanas más generales, no modales (podremos hacer otras cosas mientras estén visibles), que usaremos para mostrar textos en pantalla.

Tomando la base de "Dlg1", la aplicación con la que creamos la primera ventana de diálogo, podemos hacer otra muy parecida, pero que ahora use ventanas "normales":

 {--------------------------} 
 {  Ejemplo en Pascal:      } 
 {                          } 
 {    Ventanas de texto     } 
 {    en Turbo Vision - 1   } 
 {    VENT1.PAS             } 
 {                          } 
 {  Este fuente procede de  } 
 {  CUPAS, curso de Pascal  } 
 {  por Nacho Cabanes       } 
 {                          } 
 {  Comprobado con:         } 
 {    - Free Pascal 2.2.0w  }
 {    - Turbo Pascal 7.0    } 
 {--------------------------}
 program Vent1;
 uses App, Objects, Menus, Drivers, Views;
 const 
   cmVentana = 100;   { La orden que vamos a crear }
 type Programa = object (TApplication) 
     procedure InitStatusLine; virtual; 
     procedure HandleEvent(var Suceso: TEvent); virtual; 
     procedure Ventana; 
   end;
 procedure Programa.InitStatusLine; 
 var 
   R: TRect;               { Rectángulo de pantalla } 
 begin 
   GetExtent(R);           { Miramos cuando ocupa } 
   R.A.Y := R.B.Y - 1;     { Nos quedamos la línea inferior } 
   New(StatusLine, Init(R, 
     NewStatusDef(0, $FFFF, 
       NewStatusKey('~Alt-S~ Salir', kbAltS, cmQuit, 
       NewStatusKey('~Alt-V~ Ventana', kbAltV, cmVentana, 
       nil)), 
     nil))); 
 end;
 procedure Programa.HandleEvent(var Suceso: TEvent); 
 var 
   R: TRect; 
 begin 
   inherited HandleEvent(Suceso);       { Primero que mire el "padre" } 
   if Suceso.What = evCommand then      { Si es una orden } 
     case Suceso.Command of             { Miramos qué orden es } 
       cmVentana: Ventana; 
     end; 
 end;
 procedure Programa.Ventana; 
 var 
   R: TRect;                            { El "rectángulo" que ocupará } 
   W: PWindow;                          { La ventana en si } 
 begin 
   R.Assign(10,10,40,20);               { Definimos el tamaño } 
   W := New(PWindow,                    { Inicializamos: nueva ventana } 
     Init(R, 'Prueba',                  {   en la zona R, título Prueba } 
     wnNoNumber));                      {   y sin número de ventana } 
   InsertWindow(W);                { La insertamos en nuestro programa } 
 end;
 var Prog: Programa;
 begin 
   Prog.Init; 
   Prog.Run; 
   Prog.Done; 
 end. 

Esta vez hemos creado una ventana de texto, que recuerda a las que usa el entorno de Turbo Pascal cuando editamos nuestros programas.  Como hicimos en el apartado anterior, hemos empezado por una ventana vacía, pero antes de añadir algo en su interior quiero remarcar un par de cosas:
 

 

Así que antes de "llenar" la ventana, vamos a ver cómo darle un número. Lo haré de una forma más o menos estricta: podemos llevar cuenta del número de ventanas abiertas en cualquier parte de nuestro programa, pero lo más correcto es que sea nuestro objeto "Programa" quien lo gestione, así que le voy a añadir un campo y voy a redefinir el constructor Init. También haré que las ventanas aparezcan en posiciones aleatorias de la pantalla, para que se vean mejor:

 {--------------------------} 
 {  Ejemplo en Pascal:      } 
 {                          } 
 {    Ventanas de texto     } 
 {    en Turbo Vision - 2   } 
 {    VENT2.PAS             } 
 {                          } 
 {  Este fuente procede de  } 
 {  CUPAS, curso de Pascal  } 
 {  por Nacho Cabanes       } 
 {                          } 
 {  Comprobado con:         } 
 {    - Free Pascal 2.2.0w  }
 {    - Turbo Pascal 7.0    } 
 {--------------------------}
 program Vent2;
 uses App, Objects, Menus, Drivers, Views;
 const 
   cmVentana = 100;   { La orden que vamos a crear }
 type Programa = object (TApplication) 
     NumeroVent: byte;               { Número de ventana } 
     constructor Init;               { Vamos a ampliar el Init } 
     procedure InitStatusLine; virtual; 
     procedure HandleEvent(var Suceso: TEvent); virtual; 
     procedure Ventana; 
   end;
 constructor Programa.Init;   { Nuestra propia versión del Init } 
 begin 
   Inherited Init;            { Que hará lo mismo que la inicial } 
   NumeroVent := 0;           { Pero además prepara la variable } 
 end;
 procedure Programa.InitStatusLine; 
 var 
   R: TRect;               { Rectángulo de pantalla } 
 begin 
   GetExtent(R);           { Miramos cuando ocupa } 
   R.A.Y := R.B.Y - 1;     { Nos quedamos la línea inferior } 
   New(StatusLine, Init(R, 
     NewStatusDef(0, $FFFF, 
       NewStatusKey('~Alt-S~ Salir', kbAltS, cmQuit, 
       NewStatusKey('~Alt-V~ Ventana', kbAltV, cmVentana, 
       nil)), 
     nil))); 
 end;
 procedure Programa.HandleEvent(var Suceso: TEvent); 
 var 
   R: TRect; 
 begin 
   inherited HandleEvent(Suceso);       { Primero que mire el "padre" } 
   if Suceso.What = evCommand then      { Si es una orden } 
     case Suceso.Command of             { Miramos qué orden es } 
       cmVentana: Ventana; 
     end; 
 end;
 procedure Programa.Ventana; 
 var 
   R: TRect;                            { El "rectángulo" que ocupará } 
   W: PWindow;                          { La ventana en si } 
 begin 
   Inc(NumeroVent);                     { Una ventana más } 
   R.Assign(0,0,30,10);                 { Definimos el tamaño } 
   R.Move(random(50), random(13)); 
   W := New(PWindow,                    { Inicializamos: nuevo diálogo } 
     Init(R, 'Prueba',NumeroVent));                {   en la zona R, y título Prueba } 
   InsertWindow(W);                { Ejecutamos, sin parámetros } 
 end;
 var Prog: Programa;
 begin 
   Prog.Init; 
   Prog.Run; 
   Prog.Done; 
 end. 

 

Ahora sí, ya vamos a escribir algo dentro de la ventana.  Lo haremos exactamente igual que vimos para los diálogos, creando un rectángulo interior, que rellenaremos con "Static Text".

Como el tipo TStaticText está definido en la unidad Dialogs, tendremos que añadirla en nuestra sección de "uses".

 {--------------------------} 
 {  Ejemplo en Pascal:      } 
 {                          } 
 {    Ventanas de texto     } 
 {    en Turbo Vision - 3   } 
 {    VENT3.PAS             } 
 {                          } 
 {  Este fuente procede de  } 
 {  CUPAS, curso de Pascal  } 
 {  por Nacho Cabanes       } 
 {                          } 
 {  Comprobado con:         }
 {    - Free Pascal 2.2.0w  }  
 {    - Turbo Pascal 7.0    } 
 {--------------------------}

 program Vent3;

 uses App, Objects, Menus, Drivers, Views, Dialogs;

 const 
   cmVentana = 100;   { La orden que vamos a crear }

 type Programa = object (TApplication) 
     NumeroVent: byte;               { Número de ventana } 
     constructor Init;               { Vamos a ampliar el Init } 
     procedure InitStatusLine; virtual; 
     procedure HandleEvent(var Suceso: TEvent); virtual; 
     procedure Ventana; 
   end;

 constructor Programa.Init;   { Nuestra propia versión del Init } 
 begin 
   Inherited Init;            { Que hará lo mismo que la inicial } 
   NumeroVent := 0;           { Pero además prepara la variable } 
 end;

 procedure Programa.InitStatusLine; 
 var 
   R: TRect;               { Rectángulo de pantalla } 
 begin 
   GetExtent(R);           { Miramos cuando ocupa } 
   R.A.Y := R.B.Y - 1;     { Nos quedamos la línea inferior } 
   New(StatusLine, Init(R, 
     NewStatusDef(0, $FFFF, 
       NewStatusKey('~Alt-S~ Salir', kbAltS, cmQuit, 
       NewStatusKey('~Alt-V~ Ventana', kbAltV, cmVentana, 
       nil)), 
     nil))); 
 end;

 procedure Programa.HandleEvent(var Suceso: TEvent); 
 var 
   R: TRect; 
 begin 
   inherited HandleEvent(Suceso);       { Primero que mire el "padre" } 
   if Suceso.What = evCommand then      { Si es una orden } 
     case Suceso.Command of             { Miramos qué orden es } 
       cmVentana: Ventana; 
     end; 
 end;

 procedure Programa.Ventana; 
 var 
   R: TRect;                            { El "rectángulo" que ocupará } 
   W: PWindow;                          { La ventana en si } 
 begin 
   Inc(NumeroVent);                     { Una ventana más } 
   R.Assign(0,0,30,10);                 { Definimos el tamaño } 
   R.Move(random(50), random(13)); 
   W := New(PWindow,                    { Inicializamos: nuevo diálogo } 
     Init(R, 'Prueba',NumeroVent));                {   en la zona R, y título Prueba } 
   R.Assign(2,2,10,5);                  { Definimos una zona interior } 
   W^.Insert(New(PStaticText,           {   e insertamos texto en ella } 
     Init(R, 'Prueba de texto estático'))); 
   InsertWindow(W);                { Ejecutamos, sin parámetros } 
 end;

 var Prog: Programa;
 begin 
   Prog.Init; 
   Prog.Run; 
   Prog.Done; 
 end.

También podremos insertar botones, líneas de estado, etc. en una ventana de texto como ésta, pero el manejo se complica mucho comparado con los diálogos que vimos en el apartado anterior.

 

Finalmente, vamos a ver cómo cambiar la apariencia y propiedades de una ventana de texto.

Las ventanas tienen una serie de "flags", cuyo nombre empieza por "wf" y que nos permiten modificar su comportamiento:


Recordemos que las ventanas tenían "botones" para hacer muchas de estas cosas.   Pero Turbo Vision ya lo tiene en cuenta: si decimos que no se pueda cerrar una ventana, el botón de cierre no aparecerá siquiera.

Un último detalle antes de pasar al ejemplo: estos flags se almacenan como bits de un byte, que es el campo "flags".  Por ello, deberemos modificarlos con "and" u "or".  Por ejemplo, para fijar el bit wfClose asegurarnos de que una se podrá cerrar, podemos usar

flags := flags or wfClose;

y para que no se pueda cerrar sería

flags := flags and not wfClose;

Ahora ya, vamos a ver cómo quedaría el programita:

 {--------------------------} 
 {  Ejemplo en Pascal:      } 
 {                          } 
 {    Ventanas de texto     } 
 {    en Turbo Vision - 4   } 
 {    VENT4.PAS             } 
 {                          } 
 {  Este fuente procede de  } 
 {  CUPAS, curso de Pascal  } 
 {  por Nacho Cabanes       } 
 {                          } 
 {  Comprobado con:         } 
 {    - Free Pascal 2.2.0w  }
 {    - Turbo Pascal 7.0    } 
 {--------------------------}

 program Vent4;

 uses App, Objects, Menus, Drivers, Views, Dialogs;

 const 
   cmVentana = 100;   { La orden que vamos a crear }

 type Programa = object (TApplication) 
     NumeroVent: byte;               { Número de ventana } 
     constructor Init;               { Vamos a ampliar el Init } 
     procedure InitStatusLine; virtual; 
     procedure HandleEvent(var Suceso: TEvent); virtual; 
     procedure Ventana; 
   end;

 constructor Programa.Init;   { Nuestra propia versión del Init } 
 begin 
   Inherited Init;            { Que hará lo mismo que la inicial } 
   NumeroVent := 0;           { Pero además prepara la variable } 
 end;

 procedure Programa.InitStatusLine; 
 var 
   R: TRect;               { Rectángulo de pantalla } 
 begin 
   GetExtent(R);           { Miramos cuando ocupa } 
   R.A.Y := R.B.Y - 1;     { Nos quedamos la línea inferior } 
   New(StatusLine, Init(R, 
     NewStatusDef(0, $FFFF, 
       NewStatusKey('~Alt-S~ Salir', kbAltS, cmQuit, 
       NewStatusKey('~Alt-V~ Ventana', kbAltV, cmVentana, 
       nil)), 
     nil))); 
 end;

 procedure Programa.HandleEvent(var Suceso: TEvent); 
 var 
   R: TRect; 
 begin 
   inherited HandleEvent(Suceso);       { Primero que mire el "padre" } 
   if Suceso.What = evCommand then      { Si es una orden } 
     case Suceso.Command of             { Miramos qué orden es } 
       cmVentana: Ventana; 
     end; 
 end;

 procedure Programa.Ventana; 
 var 
   R: TRect;                            { El "rectángulo" que ocupará } 
   W: PWindow;                          { La ventana en si } 
 begin 
   Inc(NumeroVent);                     { Una ventana más } 
   R.Assign(0,0,30,10);                 { Definimos el tamaño } 
   R.Move(random(50), random(13)); 
   W := New(PWindow,                    { Inicializamos: nuevo diálogo } 
     Init(R, 'Prueba',NumeroVent));                {   en la zona R, y título Prueba } 
   R.Assign(2,2,10,5);                  { Definimos una zona interior } 
   W^.Insert(New(PStaticText,           {   e insertamos texto en ella } 
     Init(R, 'Prueba de texto estático'))); 
   W^.flags := W^.flags and not (wfClose or WfGrow); 
   InsertWindow(W);                { Ejecutamos, sin parámetros } 
 end;

 var Prog: Programa;

 begin 
   Prog.Init; 
   Prog.Run; 
   Prog.Done; 
 end.

Como se ve, la ventana ya no tiene botón de cierre ni la esquina inferior de redimensionado, pero sí que se la puede mover o ampliar totalmente.
 

Pues con esto doy por finalizada la introducción a Turbo Vision.  Con lo que hemos visto, uno ya puede hacer con una cierta facilidad que sus programas queden más "bonitos"... como mínimo.

El avanzar a partir de aquí, ya lo dejo a quien quiera.  Con esta base confío en que asuste menos acercarse a fuentes que empleen Turbo Vision, o al manual de TP, o incluso a la ayuda en línea.

Incluyo un ejemplo, que sería nuestra super Agenda ;-), pasada a Turbo Vision. En ella se puede observar que he dibujado la ventana de texto de otra forma menos rígida que la que acabo de comentar: en vez de "insertar" texto estático, defino su interior como View y luego ya lo incluyo en la ventana.  Esto es más versátil porque nos permite usar barras de desplazamiento, por ejemplo, pero también es bastante más complicado, y no sé si alguien lo llegará a usar, así que quien quiera trastear con ello, no tiene más que basarse en el ejemplo.

Si alguien quiere avanzar más y saber cómo poner también barras de desplazamiento y demás, le doy la pista clave: VIEWTEXT.PAS es un visor de texto, en el que me he basado yo para el lector de las primeras versiones del curso.  Es uno de los ejemplos que trae Turbo Pascal 7, dentro del directorio

 TP\EXAMPLES\TVFM

(o algo similar, según donde lo hayais instalado).  Venga, a jugar... :-)