Free Pascal.es


Apartado anteriorApartado siguiente

Curso de Pascal. Tema 17.3: Turbo Vision - Ventanas de diálogo.


Simplificando un poco el asunto, podemos distinguir dos tipos de ventanas en un entorno gráfico (a los que intenta imitar Turbo Vision): modales y no modales.
 

  • Una ventana modal es aquella que toma por completo el control de la aplicación, y no nos deja hacer nada más hasta que la cerramos.
  • Una ventana no modal es la que no toma el control de la aplicación, sino que podemos trabajar con otras ventanas sin necesidad de cerrar ésta.


¿Suena raro?  Con un par de ejemplos seguro que se verá claro del todo. Vamos a fijarnos en el lector del curso. podemos tener abiertas a la vez varias ventanas con textos de distintas lecciones, y saltar de una o otra, pasearnos por el menú, etc.  Son ventanas no modales.  En cambio, accedemos a alguna de las opciones de ayuda, pulsando F1 por ejemplo, no podemos acceder al menú ni a las demás ventanas que hayamos abierto, a no ser que cerremos la actual.  Es una ventana modal.

Insisto en que todo esto está simplificado.  Y ahora voy a hacer una simplificación más: esas ventanas no modales es lo que llamaré "ventanas de texto", y las veremos en el siguiente apartado; las ventanas modales como las de ayuda son las que llamaré "ventanas de diálogo".

Esto no es del todo cierto: podemos hacer que ventanas como los InputBox y MessageBox que hemos visto no sean modales, y que una ventana de texto sí lo sea, pero eso me lo salto... al menos de momento.

Volvamos a lo práctico.  Hemos visto cómo usar algunas ventanas predefinidas de Turbo Vision, que casi "se creaban solas".  Ahora vamos a ver cómo crearlas nosotros.

Deberemos crear una ventana de diálogo y ejecutarla. Primer ejemplillo, directamente:

 {--------------------------} 
 {  Ejemplo en Pascal:      } 
 {                          } 
 {    Ventanas de diálogo   } 
 {    en Turbo Vision - 1   } 
 {    DLG1.PAS              } 
 {                          } 
 {  Este fuente procede de  } 
 {  CUPAS, curso de Pascal  } 
 {  por Nacho Cabanes       } 
 {                          } 
 {  Comprobado con:         } 
 {    - Free Pascal 2.2.0w  }
 {    - Turbo Pascal 7.0    } 
 {--------------------------}
 
 program Dlg1;
 
 uses App, Objects, Menus, Drivers, Views, Dialogs; 
                                         { ^ Incluimos esta Unit }
 
 const 
   cmDialogo = 100;   { La orden que vamos a crear }
 
 type Programa = object (TApplication) 
     procedure InitStatusLine; virtual; 
     procedure HandleEvent(var Suceso: TEvent); virtual; 
     procedure Dialogo; 
   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-D~ Diálogo', kbAltD, cmDialogo, 
       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 } 
       cmDialogo: Dialogo; 
     end; 
 end;
 
 procedure Programa.Dialogo; 
 var 
   R: TRect;                            { El "rectángulo" que ocupará } 
   D: PDialog;                          { La ventana en sí } 
 begin 
   R.Assign(10,10,30,20);               { Definimos la zona de pantalla } 
   D := New(PDialog,                    { Inicializamos: nuevo diálogo } 
     Init(R, 'Prueba'));                {   en la zona R, y título Prueba } 
   ExecuteDialog(D,nil);                { Ejecutamos, sin parámetros } 
 end;
 
 var Prog: Programa;
 
 begin 
   Prog.Init; 
   Prog.Run; 
   Prog.Done; 
 end. 
 


 

Hemos creado una ventana de diálogo, pero estaba vacía.  Ahora vamos a hacer que tenga algo en su interior.


Para hacer que tenga algo en su interior, bastará con crear un nuevo rectángulo y añadirlo antes de ejecutar el diálogo:

 {--------------------------} 
 {  Ejemplo en Pascal:      } 
 {                          } 
 {    Ventanas de diálogo   } 
 {    en Turbo Vision - 2   } 
 {    DLG2.PAS              } 
 {                          } 
 {  Este fuente procede de  } 
 {  CUPAS, curso de Pascal  } 
 {  por Nacho Cabanes       } 
 {                          } 
 {  Comprobado con:         }
 {    - Free Pascal 2.2.0w  } 
 {    - Turbo Pascal 7.0    } 
 {--------------------------}
 
 program Dlg2;
 
 uses App, Objects, Menus, Drivers, Views, Dialogs; 
 
 const 
   cmDialogo = 100;   { La orden que vamos a crear }
 
 type Programa = object (TApplication) 
     procedure InitStatusLine; virtual; 
     procedure HandleEvent(var Suceso: TEvent); virtual; 
     procedure Dialogo; 
   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-D~ Diálogo', kbAltD, cmDialogo, 
       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 } 
       cmDialogo: Dialogo; 
     end; 
 end;
 
 procedure Programa.Dialogo; 
 var 
   R: TRect;                            { El "rectángulo" que ocupará } 
   D: PDialog;                          { La ventana en sí } 
 begin 
   R.Assign(10,10,30,20);               { Definimos la zona de pantalla } 
   D := New(PDialog,                    { Inicializamos: nuevo diálogo } 
     Init(R, 'Prueba'));                {   en la zona R, y título Prueba } 
   R.Assign(2,2,10,5);                  { Definimos una zona interior } 
   D^.Insert(New(PStaticText,           {   e insertamos texto en ella } 
     Init(R, 'Prueba de texto estático'))); 
   ExecuteDialog(D,nil);                { Ejecutamos, sin parámetros } 
 end;
 
 var Prog: Programa;
 
 begin 
   Prog.Init; 
   Prog.Run; 
   Prog.Done; 
 end.
 

Se va complicando, ¿verdad?   }:-)


Ahora que ya sabemos cómo "tener cosas" en un diálogo, vamos ver cómo poner varias cosas de interés ;-) , por ejemplo botones y líneas de introducción de texto:

 {--------------------------} 
 {  Ejemplo en Pascal:      } 
 {                          } 
 {    Ventanas de diálogo   } 
 {    en Turbo Vision - 3   } 
 {    DLG3.PAS              } 
 {                          } 
 {  Este fuente procede de  } 
 {  CUPAS, curso de Pascal  } 
 {  por Nacho Cabanes       } 
 {                          } 
 {  Comprobado con:         } 
 {    - Free Pascal 2.2.0w  }
 {    - Turbo Pascal 7.0    } 
 {--------------------------}
 
 program Dlg3;
 
 uses App, Objects, Menus, Drivers, Views, Dialogs;
 
 const 
   cmDialogo = 100;   { La orden que vamos a crear }
 
 type Programa = object (TApplication) 
     procedure InitStatusLine; virtual; 
     procedure HandleEvent(var Suceso: TEvent); virtual; 
     procedure Dialogo; 
   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-D~ Diálogo', kbAltD, cmDialogo, 
       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 } 
       cmDialogo: Dialogo; 
     end; 
 end;
 
 procedure Programa.Dialogo; 
 var 
   R: TRect;                            { El "rectángulo" que ocupará } 
   D: PDialog;                          { La ventana en sí } 
 begin 
   R.Assign(0,0,50,15);                 { Definimos el tamaño } 
   R.Move(15,5);                        {  y la posición } 
   D := New(PDialog,                    { Inicializamos: nuevo diálogo } 
     Init(R, 'Más vistoso'));           {   en la zona R, y título Prueba } 
   R.Assign(2,2,20,3);                  { Definimos una zona interior } 
   D^.Insert(New(PStaticText,           {   e insertamos texto en ella } 
     Init(R, 'Esto es un texto estático'))); 
   R.Assign(5,11,20,13);                { Igual para el botón } 
   D^.Insert(New(PButton, 
     Init(R, '~A~dios', cmQuit, bfNormal))); 
   R.Assign(10,7,40,8);                 { Y para la línea de entrada } 
   D^.Insert(New(PInputLine, 
     Init(R, 50)));                     {   de longitud 50 } 
   ExecuteDialog(D,nil);                { Ejecutamos, sin parámetros } 
 end;
 
 var Prog: Programa; 
 
 begin 
   Prog.Init; 
   Prog.Run; 
   Prog.Done; 
 end.


Comentarios sobre este programa:
 

  • Antes hemos visto que si un texto estático no cabía en una línea, seguía en las sucesivas hasta el final de la ventana.
  • Ahora sólo había una línea; en cualquier caso, si el texto no cabe entero, se parte en un espacio entre palabras, no se rompen las palabras.
  • El botón se define de forma parecida, pero parece que el comando cmQuit "no se ejecuta".  Esto no es del todo cierto.  Se ejecutaría para el HandleEvent propio del diálogo, no el de todo el programa. De momento sólo responde a "Esc", que le manda la señal de cancelar (cmCancel), a la que sí sabe responder. bfNormal es uno de los "button flags", indicadores específicos para los botones.  Cuando tengamos varios botones en una ventana, podremos usar bfDefault en uno de ellos para indicar que ése será el botón por defecto (el que se pulsará con Intro).
  • La línea de entrada de datos permite 50 caracteres de longitud, pero esta creada en un rectángulo de 30 (40-10) caracteres de anchura. Eso no es problema, porque no hace falta ver todo el texto a la vez, como podeis comprobar si tecleais un texto largo.



Finalmente, vamos a ver cómo añadir una etiqueta que identifique a esa línea de entrada de datos, y como trabajar con los datos de dicha línea:

 {--------------------------} 
 {  Ejemplo en Pascal:      } 
 {                          } 
 {    Ventanas de diálogo   } 
 {    en Turbo Vision - 4   } 
 {    DLG4.PAS              } 
 {                          } 
 {  Este fuente procede de  } 
 {  CUPAS, curso de Pascal  } 
 {  por Nacho Cabanes       } 
 {                          } 
 {  Comprobado con:         } 
 {    - Free Pascal 2.2.0w  }
 {    - Turbo Pascal 7.0    } 
 {--------------------------}
 
 program Dlg4;
 
 uses App, Objects, Menus, Drivers, Views, Dialogs, MsgBox;
 
 const 
   cmDialogo = 100;   { La orden que vamos a crear }
 
 type Programa = object (TApplication) 
     texto: string; 
     procedure InitStatusLine; virtual; 
     procedure HandleEvent(var Suceso: TEvent); virtual; 
     procedure Dialogo; 
   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-D~ Diálogo', kbAltD, cmDialogo, 
       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 } 
       cmDialogo: Dialogo; 
     end; 
 end;
 
 procedure Programa.Dialogo; 
 var 
   R: TRect;                            { El "rectángulo" que ocupará } 
   D: PDialog;                          { La ventana en sí } 
   Enlace: PView;                       { Para la enlazar la etiqueta 
                                          con la InputLine } 
 begin 
   Texto := 'Texto por defecto';        { Texto inicial } 
   R.Assign(0,0,50,15);                 { Definimos el tamaño } 
   R.Move(15,5);                        {  y la posición } 
   D := New(PDialog,                    { Inicializamos: nuevo diálogo } 
     Init(R, 'Más vistoso'));           {   en la zona R, y título Prueba } 
   R.Assign(2,2,20,3);                  { Definimos una zona interior } 
   D^.Insert(New(PStaticText,           {   e insertamos texto en ella } 
     Init(R, 'Esto es un texto estático'))); 
   R.Assign(5,11,20,13);                { Igual para el primer botón } 
   D^.Insert(New(PButton, 
     Init(R, '~C~ancelar', cmCancel, bfNormal))); 
   R.Assign(25,11,40,13);                { Y para el segundo } 
   D^.Insert(New(PButton, 
     Init(R, '~A~ceptar', cmOK, bfDefault))); 
   R.Assign(10,7,40,8);                 { Y para la línea de entrada } 
   Enlace := New(PInputLine, Init(R, 50)); 
   D^.Insert(Enlace); 
   R.Assign(9,6,30,7);                 { Y la etiqueta asociada } 
   D^.Insert(New(PLabel, 
     Init(R, 'Texto:', Enlace))); 
   ExecuteDialog(D,@Texto);            { Ejecutamos, CON parámetros } 
   MessageBox('Ha tecleado: '+ Texto,  { Y mostramos el resultado } 
            nil, mfInformation or mfOKButton); 
 end;
 
 var Prog: Programa; 
 
 begin 
   Prog.Init; 
   Prog.Run; 
   Prog.Done; 
 end.

En un diálogo también podemos poner casillas de verificación de opciones, visores de listas, etc., pero eso lo dejo para que lo investigue quien tenga muchas inquietudes.

Diseñar diálogos "a pelo" puede ser algo muy pesado.  En muchas BBS y en Internet podremos encontrar utilidades que nos permiten hacerlo de forma "visual", como DLGDSN (Dialog Design, de L. David Baldwin)

(Nota: todo esto está realizado con TP7; no lo he probado en TP6).
 

Apartado anteriorApartado siguiente

Novedad!

Buscar

Google
 

   en la Web
   en www.freepascal.es

Qué es

Descargas

Aprende