viernes, 24 de mayo de 2013

Programando en Borland C++ 5.02 (Cap.III)

Hola de nuevo, amigos del Blog.
 
En la pasada entrega dijimos que este capítulo estaría dedicado a la simulación de botones en modo texto pero esto va ligado al uso del ratón y otras funciones más complejas por lo que lo dejaremos para más adelante.
 
En esta entrega hablaremos del tratamiento de fechas y horas.
 
Es habitual que en los programas informáticos se necesite la gestión de estos datos. Suele ser bastante tedioso, por eso, para facilitar esta labor crearemos unas funciones que nos ayuden en su tratamiento y gestión.
 
Veremos cómo dar formato a las fechas de manera que se visualicen con distintas plantillas. Ej.: "27 de abril de 2013" o "27-Abr-2013" o "27/04/13", etc.
 
Usaremos la Fecha Juliana o Día Juliano y veremos su utilidad a la hora de almacenar la información o realizar cálculos con fechas.

También veremos el COMPUTUS o cálculo de la fecha de Pascua.
 
La fecha juliana es el número de días y fracción transcurridos desde el mediodía del 1º de enero del año 4713 a. C. Así la fecha juliana es una cuenta continua de días y fracciones contados desde un punto inicial fijo.
 
Como ejemplo, para el 15 de mayo de 2013, a las 11:31 TU, la fecha juliana es 2456427.9798611. La parte entera (2456427) corresponde al día desde el mediodía pasado hasta el próximo mediodía y los decimales indican la fracción de día transcurrida desde el último mediodía (de forma que 0,5 sería la medianoche).
 
La fecha Juliana 2451545.0 corresponde al día 1 de enero de 2000, mediodía TT. (Tiempo Terrestre)
 
Los días julianos también sirven para indicar la hora, expresándose esta como una fracción de un día entero, siendo las 12 del mediodía el punto cero. Así, las tres de la tarde del 1 de enero de 1970 es DJ 2440588,125 (ya que las tres de la tarde son tres horas después de mediodía, y 3/24 = 0,125 días). El día juliano viene siempre determinado por el tiempo universal y no por el local.
 
Para información más completa sobre la Fecha Juliana, referíos a Google.
 
La Pascua, festividad principal de la Semana Santa, tiene su origen en el judaísmo. Lla pascua judía, Pésaj, celebra la salida del pueblo judío de Egipto, que tenía lugar el día 14 de Nisán, el primer mes del calendario judío. El calendario judío, como muchos otros, era un calendario lunar y el año comenzaba con el equinoccio de primavera, por lo que el día 14 de Nisán se correspondía con la primera luna llena después del equinoccio de primavera.
 
El cristianismo, mantuvo esta celebración en sus órigenes, pero ya el papa Sixto I, en torno al año 120, movió esta celebración para que tuviera lugar el primer domingo después de Pésaj, estableciendo de este modo una diferencia. Así mismo, este día pasaría a celebrar la resurrección de Jesucristo en vez de la liberación del pueblo judío.
 
Esta decisión no tuvo carácter oficial hasta que en el año 314 en el Concilio de Arlés se declaró como obligatoria la celebración de la Pascua el mismo día en toda la cristiandad, siendo ese día elegido por el Papa de Roma. Once años más tarde, en el Concilio de Nicea del 325, se establecieron las primeras normas de cálculo de la Pascua, que debido a las discrepancias entre la Iglesia de Roma y la Iglesia de Alejandría, fueron reformadas en el 525 por Dionisio el Exiguo, consiguiendo por primera vez un consenso global, que se ha extendido hasta el día de hoy en todo occidente.
 
Las reglas de cálculo son:
1) La Pascua cae en domingo.
2) El domingo elegido es el primer domingo después de la primera luna llena de la primavera boreal. En caso de que esta fecha fuese domingo, la Pascua se trasladaría al domingo siguiente para no coincidir con Pésaj.
3) La primavera comienza con el equinoccio de primavera, que tiene lugar el 21 de Marzo.
 
Computus, es el cálculo de la fecha de Pascua.
 
Una vez más, para profundizar en la información, navegad por vuestros buscadores favoritos.
 
Y ahora, al código.
 
Para hacer uso de estas funciones debéis referenciar las siguientes URLS:
 
 
#include <conio.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <dos.h>
#include <windows.h>
#include <iostream.h>
#include <Wincon.h>
#include <mem.h>
#include <stdlib.h>
#include <sys\timeb.h>
#include <tchar.h>
#include <math.h>
 
//Algunos includes no son necesarios pero tampoco estorban...
 
struct rHora  { int Hor; int Min; int Sec; };
struct rFecha  { int Ano; int Mes; int Dia; };
struct rFechaExt { int Ano; int Mes; int Dia; int Hor; int Min; int
Seg; double DiaJul; int Bissto; int PscDia; int PscMes; int AnoSem; int AnoDia; int DiaSem; char DiaStr[10]; char MesStr[11];};
 
//==============================================================================
//Declaracion de variables GLOBALES
//==============================================================================
char Meses[12][11] = {"Enero","Febrero","Marzo","Abril","Mayo","Junio","Julio","Agosto","Septiembre","Octubre","Noviembre","Diciembre"};
int Mdias[12]  = {31,28,31,30,31,30,31,31,30,31,30,31};
char Dias [ 7][10] = {"Lunes","Martes","Miercoles","Jueves","Viernes","Sabado","Domingo"};
//==============================================================================
int Bisiesto(int A)
{
 if (((A % 4)==0) && ((A % 100)!=0 || (A % 400)==0)) return 1; //Si Bisiesto
 else return 0;                 //No Bisiesto
}
//==============================================================================
int DiaJuliano (int A, int M, int D)
{
 //Funciona entre 1801 y 2099
   return D-32075+1461*(A+4800+(M-14)/12)/4+367*(M-2-(M-14)/12*12)/12-3*((A+4900+(M-14)/12)/100)/4;
}
//==============================================================================
int DiaSemana(double DiaJuliano)
{
   double Total  = DiaJuliano + 0.5;
   return int( (Total/7 - int(Total/7))*7 + 0.000000000317 ) + 1;
}
//==============================================================================
void FechaSemDia (rFechaExt &Fec)
{
 int AuxAno = Fec.Ano;
 int FaseB, FaseC, FaseS, FaseE, FaseG, FaseN;
 int DiaSec, DiaSem, NumSem;
 
 if (Fec.Mes < 3) AuxAno = AuxAno - 1;
 
 FaseB = AuxAno / 4 - AuxAno / 100 + AuxAno / 400;
 FaseC = (AuxAno - 1) / 4 - (AuxAno - 1) / 100 + (AuxAno - 1) / 400;
 FaseS = FaseB - FaseC;
 
 if (Fec.Mes < 3)
 {  FaseE = 0;    DiaSec = Fec.Dia - 1 + 31 * (Fec.Mes - 1); }
 else
 { FaseE = FaseS + 1; DiaSec = Fec.Dia + ((Fec.Mes - 3) * 153 + 2) / 5 + 58 + FaseS; }
 
 FaseG  = (AuxAno + FaseB) % 7;
 DiaSem = (DiaSec + FaseG - FaseE) % 7;
 FaseN  = DiaSec + 3 - DiaSem;
 NumSem = FaseN / 7 + 1;
 
 if (FaseN < 0)     NumSem = 53 - (FaseG - FaseS) / 5;
 if (FaseN > 364 + FaseS) NumSem = 1;
 
 DiaSem  = DiaSem + 1;
 DiaSec  = DiaSec + 1;
 Fec.DiaSem = DiaSem;        //Dia de la Semana
 Fec.AnoDia = DiaSec;        //Dia secuencial en el año
 Fec.AnoSem = NumSem;        //Semana del año
}
//==============================================================================
void FechJul (rFecha Fecha, int &DiasJul)
{
 int DiasMes;
 int Dato[12] = {0,31,59,90,120,151,181,212,243,273,304,334};
 DiasJul = (4712 + Fecha.Ano) * 365.25;
 if (DiasJul == int(DiasJul)) DiasJul = DiasJul - 1;
 else         DiasJul = int(DiasJul);
 if (((Fecha.Ano >= 1583 || Fecha.Ano == 1582  && (Fecha.Mes > 10 || (Fecha.Mes == 10 && Fecha.Dia >= 15)))) && Fecha.Ano <= 1700) DiasJul = DiasJul - 10;
 if (1701 <= Fecha.Ano && Fecha.Ano <= 1800) DiasJul = DiasJul - 11;
 if (1801 <= Fecha.Ano && Fecha.Ano <= 1900) DiasJul = DiasJul - 12;
 if (1901 <= Fecha.Ano && Fecha.Ano <= 2100) DiasJul = DiasJul - 13;
 if (2101 <= Fecha.Ano && Fecha.Ano <= 2200) DiasJul = DiasJul - 14; //etc...
 DiasMes = Dato[Fecha.Mes - 1];    //Días transcurridos hasta el mes de la fecha
 //*****************************
 //Miramos si el año es bisiesto
 //*****************************
 if (Fecha.Ano < 1582) goto SALTO ;    //Si el año es del periodo Juliano
 if ( Fecha.Ano / 4   != int(Fecha.Ano / 4)) goto CALC;
 if ((Fecha.Ano / 100 == int(Fecha.Ano / 100)) && (Fecha.Ano / 400 != int(Fecha.Ano / 400))) goto CALC;
SALTO:
 if (Fecha.Mes <= 2) goto CALC;    //Si es Enero o Febrero no influye el bisiesto
 DiasMes = DiasMes + 1;       //El año es bisiesto, añadimos 1
CALC:
 DiasJul = DiasJul + DiasMes + Fecha.Dia;
}
//==============================================================================
void FechaPascua (rFechaExt &Fec)
{
 int constMes, constn;
   int VarA, VarB, VarC, VarD, VarE, DiaPascua, MesPascua;
 if (Fec.Ano >= 1583 && Fec.Ano <= 1699) constMes = 22; constn = 2;
   if (Fec.Ano >= 1700 && Fec.Ano <= 1799) constMes = 23; constn = 3;
   if (Fec.Ano >= 1800 && Fec.Ano <= 1899) constMes = 23; constn = 4;
   if (Fec.Ano >= 1900 && Fec.Ano <= 2099) constMes = 24; constn = 5;
   if (Fec.Ano >= 2100 && Fec.Ano <= 2199) constMes = 24; constn = 6;
   if (Fec.Ano >= 2200 && Fec.Ano <= 2299) constMes = 25; constn = 0;
 VarA = Fec.Ano % 19;
 VarB = Fec.Ano % 4;
 VarC = Fec.Ano % 7;
 VarD = (19 * VarA + constMes) % 30;
 VarE = ( 2 * VarB + 4 * VarC + 6 * VarD + constn) % 7;
 if (VarD + VarE < 10)
   { DiaPascua = VarD + VarE + 22; MesPascua = 3; }
 else
   { DiaPascua = VarD + VarE - 9; MesPascua = 4;
    if   (DiaPascua == 26) DiaPascua = 19;
  else if (DiaPascua == 25 && VarD == 28 && VarE == 6 && VarA > 10) DiaPascua = 18;
   }
 Fec.PscDia = DiaPascua;
 Fec.PscMes = MesPascua;
}
//==============================================================================
void FechazResto (rFechaExt &Fec)
{
 FechaPascua(Fec);
 FechaSemDia(Fec);
 Fec.Bissto = Bisiesto(Fec.Ano);
   strcpy (Fec.DiaStr, Dias [Fec.DiaSem-1]);
   strcpy (Fec.MesStr, Meses[Fec.Mes-1]);
}
//==============================================================================
void FechaGetJul (rFechaExt &Fec)
{
   double jd, fraccion, decimal;
   int  DiaSemana;
  
  jd = 367.0 * Fec.Ano - (7 * (Fec.Ano + ((Fec.Mes + 9) / 12)) / 4) + (275 * Fec.Mes / 9) + Fec.Dia + 1721013;
  
  fraccion = Fec.Hor / 24.0 - 0.5;
 
  if (fraccion >= 0) jd = jd + 1;
  if (fraccion < 0) fraccion = fraccion + 1;
  
  DiaSemana = fmod(jd, 7) + 1;
  decimal = fraccion + (Fec.Min + Fec.Seg / 60.0) / 60.0 / 24.0;
  jd = jd + decimal;
  Fec.DiaJul = jd;
  Fec.DiaSem = DiaSemana;
  FechazResto(Fec);
}
//==============================================================================
void FechaGetFec (rFechaExt &Fec)
{
 
int  intgr;
 int  tmp, j1, j2, j3, j4, j5;
 int  Dia, Mes, Ano, Hor, Min, Sec;
 double frac, dayfrac, F;
  
 intgr = int(Fec.DiaJul);
 frac  = Fec.DiaJul - intgr;
 
 if (intgr >= 2299161)     //Gregorian calendar correction
 {
  tmp = int(((intgr - 1867216) - .25) / 36524.25);
  j1 = intgr + 1 + tmp - int(.25 * tmp);
 }
 else j1 = intgr;
 
 dayfrac = frac + .5;      //correction for half day offset
 
 if (dayfrac >= 1)
 {
  dayfrac = dayfrac - 1;
  j1 = j1 + 1;
 }
 
 j2 = j1 + 1524;
 j3 = int(6680 + ((j2 - 2439870) - 122.1) / 365.25);
 j4 = int(j3 * 365.25);
 j5 = int((j2 - j4) / 30.6001);
 Dia = int(j2 - j4 - int(j5 * 30.6001));
 Mes = int(j5 - 1);
 Ano = int(j3 - 4715);
 if (Mes >  12) Mes = Mes - 12;
 if (Mes >  2 ) Ano = Ano - 1;
 if (Ano <= 0)  Ano = Ano - 1;
 Hor = int( dayfrac * 24);
 Min = int((dayfrac * 24 - Hor) * 60);
 F = ((dayfrac * 24 - Hor) * 60 - Min) * 60;
 Sec = int(F);
 F = F - Sec;
 if (  F > .5) Sec = Sec + 1;
 if (Ano <  0) Ano = -Ano;
 Fec.Ano = Ano;
 Fec.Mes = Mes;
 Fec.Dia = Dia;
 Fec.Hor = Hor;
 Fec.Min = Min;
 Fec.Seg = Sec;
 FechazResto(Fec);
}
//==============================================================================
int ValidaFechaExt ( rFechaExt Fec )
{
 int ErrorFecha = 0;
 if ( Fec.Ano >  9999 || Fec.Ano < 1 )       ErrorFecha = 8;
 if ( Fec.Mes <  1  || Fec.Mes > 12 )       ErrorFecha = 1;
 if ( Fec.Hor <  0  || Fec.Hor > 24 )       ErrorFecha = 2;
 if ( Fec.Min <  0  || Fec.Min > 60 )       ErrorFecha = 3;
 if ( Fec.Seg <  0  || Fec.Seg > 60 )       ErrorFecha = 4;
 if ( Fec.Hor == 24  && (Fec.Min > 0  || Fec.Seg > 0) ) ErrorFecha = 5;
 if ( Fec.Min == 60  && Fec.Seg > 0 )       ErrorFecha = 6;
 if ( Fec.Dia < 1 ) ErrorFecha = 7;
 switch ( Fec.Mes )
 {
  case 1, 3, 5, 7, 8, 10, 12: if ( Fec.Dia > 31 ) ErrorFecha = 7;
  case 4, 6, 9, 11:     if ( Fec.Dia > 30 ) ErrorFecha = 7;
  case 2:
   if (Bisiesto(Fec.Ano))
    if (Fec.Dia > 29) ErrorFecha = 7;
   else
    if (Fec.Dia > 28) ErrorFecha = 7;
 }
    return ErrorFecha;
}
 
//==============================================================================
//==============================================================================
void main()
{
   //---------------------------------------------------------------------------
   int D, M, Y;
   Y=2001;
   printf ("¿Es bisiesto el año %i ? = %i \n", Y, Bisiesto(Y));
   Y=1960;
   printf ("¿Es bisiesto el año %i ? = %i \n", Y, Bisiesto(Y));
   printf("\n");
   //---------------------------------------------------------------------------
 rFecha F;
   int  DiasJul;
 F.Ano=1960;
   F.Mes=8;
   F.Dia=31;
   FechJul(F, DiasJul);
   printf("   FechJul-> Para la Fecha %i-%i-%i, el dia Juliano es: %i \n", F.Ano, F.Mes, F.Dia, DiasJul);
   printf("\n");
   //---------------------------------------------------------------------------
   Y=F.Ano;
   M=F.Mes;
   D=F.Dia;
   printf("DiaJuliano-> Para la Fecha %i-%i-%i, el dia Juliano es: %i \n", Y,M,D,DiaJuliano(Y, M, D));
   printf("\n");
   //---------------------------------------------------------------------------
   printf(" DiaSemana-> Para el dia Juliano %i el dia de la semana es: %i \n", DiaJuliano(Y, M, D), DiaSemana(DiaJuliano(Y, M, D)));
   printf("\n");

   //---------------------------------------------------------------------------
   rFechaExt Fec;
   Fec.Ano=2000;
   Fec.Mes=1;
   Fec.Dia=1;
   Fec.Hor=12;
   Fec.Min=0;
   Fec.Seg=0;
   Fec.DiaJul=0;
   Fec.Bissto=-1;
   Fec.PscDia=0;
   Fec.PscMes=0;
   Fec.AnoSem=0;
   Fec.AnoDia=0;
   Fec.DiaSem=0;
   strcpy(Fec.DiaStr, "");
   strcpy(Fec.MesStr, "");
   printf("Para la Fecha/Hora: %i-%i-%i %i:%i:%i \n", Fec.Ano, Fec.Mes, Fec.Dia, Fec.Hor, Fec.Min, Fec.Seg);
   printf(" El dia Juliano es: %f \n", Fec.DiaJul);
   printf("          Bisiesto: %i \n", Fec.Bissto);
 printf(" Domingo de Pascua: Dia=%i Mes=%i \n",  Fec.PscDia, Fec.PscMes);
   printf("    Semana del ano: %i --> %s \n", Fec.AnoSem, Fec.MesStr);
   printf("       Dia del ano: %i \n", Fec.AnoDia);
   printf("  Dia de la semana: %i --> %s - %s\n", Fec.DiaSem, Fec.DiaStr, Fec.MesStr);
   printf("\n");
   FechaSemDia(Fec);
   printf("FechaSemDia \n");
   printf("Para la Fecha/Hora: %i-%i-%i %i:%i:%i \n", Fec.Ano, Fec.Mes, Fec.Dia, Fec.Hor, Fec.Min, Fec.Seg);
   printf(" El dia Juliano es: %f \n", Fec.DiaJul);
   printf("          Bisiesto: %i \n", Fec.Bissto);
 printf(" Domingo de Pascua: Dia=%i Mes=%i \n",  Fec.PscDia, Fec.PscMes);
   printf("    Semana del ano: %i \n", Fec.AnoSem);
   printf("       Dia del ano: %i \n", Fec.AnoDia);
   printf("  Dia de la semana: %i --> %s - %s\n", Fec.DiaSem, Fec.DiaStr, Fec.MesStr);
   printf("\n");
   FechaPascua(Fec);
   printf("FechaPascua \n");
   printf("Para la Fecha/Hora: %i-%i-%i %i:%i:%i \n", Fec.Ano, Fec.Mes, Fec.Dia, Fec.Hor, Fec.Min, Fec.Seg);
   printf(" El dia Juliano es: %f \n", Fec.DiaJul);
   printf("          Bisiesto: %i \n", Fec.Bissto);
 printf(" Domingo de Pascua: Dia=%i Mes=%i \n",  Fec.PscDia, Fec.PscMes);
   printf("    Semana del ano: %i \n", Fec.AnoSem);
   printf("       Dia del ano: %i \n", Fec.AnoDia);
   printf("  Dia de la semana: %i --> %s - %s\n", Fec.DiaSem, Fec.DiaStr, Fec.MesStr);
   printf("\n");
   FechazResto(Fec);
   printf("FechazResto \n");
   printf("Para la Fecha/Hora: %i-%i-%i %i:%i:%i \n", Fec.Ano, Fec.Mes, Fec.Dia, Fec.Hor, Fec.Min, Fec.Seg);
   printf(" El dia Juliano es: %f \n", Fec.DiaJul);
   printf("          Bisiesto: %i \n", Fec.Bissto);
 printf(" Domingo de Pascua: Dia=%i Mes=%i \n",  Fec.PscDia, Fec.PscMes);
   printf("    Semana del ano: %i \n", Fec.AnoSem);
   printf("       Dia del ano: %i \n", Fec.AnoDia);
   printf("  Dia de la semana: %i --> %s - %s\n", Fec.DiaSem, Fec.DiaStr, Fec.MesStr);
   printf("\n");
   FechaGetJul(Fec);
   printf("FechaGetJul \n");
   printf("Para la Fecha/Hora: %i-%i-%i %i:%i:%i \n", Fec.Ano, Fec.Mes, Fec.Dia, Fec.Hor, Fec.Min, Fec.Seg);
   printf(" El dia Juliano es: %f \n", Fec.DiaJul);
   printf("          Bisiesto: %i \n", Fec.Bissto);
 printf(" Domingo de Pascua: Dia=%i Mes=%i \n",  Fec.PscDia, Fec.PscMes);
   printf("    Semana del ano: %i \n", Fec.AnoSem);
   printf("       Dia del ano: %i \n", Fec.AnoDia);
   printf("  Dia de la semana: %i --> %s - %s\n", Fec.DiaSem, Fec.DiaStr, Fec.MesStr);
   printf("\n");
 Fec.Ano=0;
   Fec.Mes=0;
   Fec.Dia=0;
   Fec.Hor=0;
   Fec.Min=0;
   Fec.Seg=0;
   Fec.DiaJul=2437178;
   Fec.Bissto=-1;
   Fec.PscDia=0;
   Fec.PscMes=0;
   Fec.AnoSem=0;
   Fec.AnoDia=0;
   Fec.DiaSem=0;
   strcpy(Fec.DiaStr, "");
   strcpy(Fec.MesStr, "");
   printf("FechaGetJul \n");
   printf("Para la Fecha/Hora: %i-%i-%i %i:%i:%i \n", Fec.Ano, Fec.Mes, Fec.Dia, Fec.Hor, Fec.Min, Fec.Seg);
   printf(" El dia Juliano es: %f \n", Fec.DiaJul);
   printf("          Bisiesto: %i \n", Fec.Bissto);
 printf(" Domingo de Pascua: Dia=%i Mes=%i \n",  Fec.PscDia, Fec.PscMes);
   printf("    Semana del ano: %i \n", Fec.AnoSem);
   printf("       Dia del ano: %i \n", Fec.AnoDia);
   printf("  Dia de la semana: %i --> %s - %s\n", Fec.DiaSem, Fec.DiaStr, Fec.MesStr);
   printf("\n");

   FechaGetFec(Fec);
   printf("FechaGetJul \n");
   printf("Para la Fecha/Hora: %i-%i-%i %i:%i:%i \n", Fec.Ano, Fec.Mes, Fec.Dia, Fec.Hor, Fec.Min, Fec.Seg);
   printf(" El dia Juliano es: %f \n", Fec.DiaJul);
   printf("          Bisiesto: %i \n", Fec.Bissto);
 printf(" Domingo de Pascua: Dia=%i Mes=%i \n",  Fec.PscDia, Fec.PscMes);
   printf("    Semana del ano: %i \n", Fec.AnoSem);
   printf("       Dia del ano: %i \n", Fec.AnoDia);
   printf("  Dia de la semana: %i --> %s - %s\n", Fec.DiaSem, Fec.DiaStr, Fec.MesStr);
   printf("\n");
   float t  = Fec.DiaJul + 0.5;
   int wd = int( (t/7 - int(t/7))*7 + 0.000000000317 );
 printf("%s", Dias[wd]);

 getch();
}
//==============================================================================

 
De esta manera, si almacenáis la fecha en formato Juliano, en una variable "double" se guardará la fecha y la hora, con su consiguiente ahorro de espacio. También será más fácil su ordenación y el cálculo de sumas y restas entre fechas.
 
Hay funciones que están escritas con distintos algoritmos.
 
Espero que estas funciones os sirvan y os ayuden en vuestros programas.
 
Saludos y hasta la próxima.
 
Si os ha gustado suscribíos a mi canal y compartid esta entrada.

Gracias a todos.
 

viernes, 19 de abril de 2013


Programando en Borland C++ 5.02 (Cap.II)

Hola amigos del Blog.
En esta entrega aprenderemos a pintar en pantalla “Cajas” o rectángulos mediante rutinas que faciliten la tarea.
Las “Cajas” podrán tener borde de distintos tipos (simple, doble, ancho…) y con su color propio.
Para ello nos crearemos una estructura que contenga la información de cada una de nuestras “Cajas”.

struct rCaja
{int Fila, Columna, Largo, Alto, Tinta, Papel, Marco, Fondo;} Caja;

Parece que todos los elementos se entienden con claridad. El elemento ”Fondo” se usa para poner el color de fondo en casos en el que el ”Marco” sea especial como veremos en el ejemplo.
De esta manera, en nuestro programa principal bastaría con llamar a la función “PintaCaja” con los elementos de la estructura debidamente asignados, para pintar una “Caja” en pantalla.
Veamos cómo quedaría la función y el programa principal:

#include   <conio.h>
#include   <stdio.h>
#include   <string.h>
#include   <time.h>
#include   <dos.h>
#include   <windows.h>

//======================================================================
// Colores
// http://sertocestutoriales.blogspot.com.es/
// https://www.youtube.com/user/sertoces
//=======================================================================
 

#define NEGRO    0
#define AZUL     1
#define VERDE    2
#define CYAN     3
#define GRANATE  4
#define MORADO   5
#define MARRON   6
#define BLANCO   7
#define GRIS     8
#define AZULB    9
#define VERDEB   10
#define CYANB    11
#define ROJO     12
#define LILA     13
#define AMARILLO 14
#define BLANCOB  15
#define BRILLO   128
 
struct rCaja
{ int Fila, Columna, Largo, Alto, Tinta, Papel, Marco, Fondo; } Caja;

//========================================================================
// Funcion Caja

// http://sertocestutoriales.blogspot.com.es/
// https://www.youtube.com/user/sertoces
//========================================================================
 
 
void PintaCaja (rCaja Caja)
{
 char ESI, ESD, EII, EID, HS, HI, VI, VD;
 int  i, j, PapelEsp;
  _setcursortype(_NOCURSOR);
 PapelEsp=Caja.Papel;
 if (Caja.Marco <0) //Si es menor que cero nos Mandan un character determinado
 {   //lo convertimos a positivo y lo usamos como MARCO.
  i = Caja.Marco*-1;
  ESI=i; ESD=i; EII=i; EID=i; HS=i; HI=i; VI=i; VD=i;
 }
 else
 //En función del tipo de MARCO inicializamos las esquinas y las líneas Verticales y
 //Horizontales
 switch (Caja.Marco)
 {
  case 1:  ESI=218; ESD=191; EII=192; EID=217; HS=196; HI=196; VI=179; VD=179;  break; //Linea simple
  case 2:  ESI=201; ESD=187; EII=200; EID=188; HS=205; HI=205; VI=186; VD=186;  break; //Linea doble
  case 3:  ESI=219; ESD=219; EII=219; EID=219; HS=223; HI=220; VI=219; VD=219;  break; //Linea ancha
  case 4:  ESI=220; ESD=220; EII=223; EID=223; HS=220; HI=223; VI=219; VD=219;  break; //Linea Ancha corta
  case 5:  ESI=219; ESD=219; EII=223; EID=223; HS=223; HI=223; VI=219; VD=219;  break; //Linea Ancha corta-abajo
  case 6:  ESI=220; ESD=220; EII=219; EID=219; HS=220; HI=220; VI=219; VD=219;  break; //Linea Ancha corta-arriba
  case 7:  ESI= 43; ESD= 43; EII= 43; EID= 43; HS= 45; HI= 45; VI=221; VD=221;  break; //Linea texto
  case 8:  ESI=254; ESD=254; EII=254; EID=254; HS=254; HI=254; VI=254; VD=254;  break; //Linea puntos
  case 9:  ESI=250; ESD=250; EII=250; EID=250; HS=250; HI=250; VI=250; VD=250;  break; //Linea puntos
  default: ESI= 32; ESD= 32; EII= 32; EID= 32; HS= 32; HI= 32; VI= 32; VD= 32;  break;
 }
 gotoxy (Caja.Columna, Caja.Fila);
 if (Caja.Marco==4 || Caja.Marco==6) PapelEsp=Caja.Fondo;
 if (PapelEsp>7) textcolor(Caja.Tinta+BRILLO); else textcolor(Caja.Tinta);
 textbackground(PapelEsp);
 cprintf("%c",ESI);
 for (i = 1; i < Caja.Largo-1; i++) cprintf("%c",HS);
 cprintf("%c",ESD);
 if (Caja.Papel>7) textcolor(Caja.Tinta+BRILLO); else textcolor(Caja.Tinta);
 textbackground(Caja.Papel);
 
 for (j=1; j<Caja.Alto-2; j++)
 {
  gotoxy (Caja.Columna, Caja.Fila+j);
  cprintf("%c",VI);
  for (i = 1; i < Caja.Largo-1; i++) cprintf("%c",32);
  cprintf("%c",VD);
 }
 if (Caja.Marco==4 || Caja.Marco==5) PapelEsp=Caja.Fondo; else PapelEsp=Caja.Papel;
 gotoxy (Caja.Columna, Caja.Fila+j);
 if (PapelEsp>7) textcolor(Caja.Tinta+BRILLO); else textcolor(Caja.Tinta);
 textbackground(PapelEsp);
 cprintf("%c",EII);
 for (i = 1; i < Caja.Largo-1; i++) cprintf("%c",HI);
 cprintf("%c",EID);
}
//========================================================================
// FIN Funcion Caja
//========================================================================


//************************************************************************ 
//************************************************************************

//========================================================================
// Programa principal
//========================================================================
main()
{
 //--------------------------------------------------------------------
 //Test de Caja
 //--------------------------------------------------------------------
 gotoxy(20,2);
 printf("Pulsa una tecla");

rCaja MyCaja;
 MyCaja.Fila = 1;
 MyCaja.Columna = 60;
 MyCaja.Largo = 20;
 MyCaja.Alto = 26;
 MyCaja.Tinta = CYANB;
 MyCaja.Papel = VERDE;
 MyCaja.Fondo = AMARILLO;
 for (MyCaja.Marco = 0; MyCaja.Marco < 10; MyCaja.Marco++)
 {
  PintaCaja (MyCaja);
  getch();
 }
}
//=======================================================================
// FIN Programa principal

// http://sertocestutoriales.blogspot.com.es/
// https://www.youtube.com/user/sertoces
//=======================================================================


Os dejo como tarea pintar un “efecto sombra” a la “Caja”.

Espero que os sea útil e instructivo.

En la próxima entrega veremos cómo se pueden simular “Botones”.


Si os ha gustado suscribíos a mi canal y compartid esta entrada.



Gracias a todos.

miércoles, 3 de abril de 2013

INICIACIÓN Y APRENDIZAJE DE PROGRAMACIÓN-C++-CAP 1


Programa C++ ión
Esta sección ayudará a los que se estén iniciando en la programación en C++ con Borland a desarrollar programas más rápidamente gracias al uso de rutinas que engloban el uso de sentencias repetitivas, como el printf(…), textcolor(…), gotoxy(…), etc.
También incorporaré rutinas para crear menús fácilmente, impresión de texto, impresión de números, recuadros de diversos tipos, etc.
Hoy facilitaremos la impresión de variables de texto (char) en pantalla.
Como sabéis, para imprimir texto en color en una zona concreta de la pantalla hay que usar las funciones gotoxy(columna, fila) para situarse en la zona de la pantalla en donde queremos pintar el dato, textcolor(…) y textbackground(…)para poner color de texto y color de fondo y por último el cprintf(…) con el formato correspondiente.
Pues bien, en nuestro código fuente esto quedaría así (más o menos):
gotoxy(10,20);            //situarse en la columna 10, fila 20
textcolor(10);            //texto en verde brillante
textbackground(4);        //fondo en granate
cprintf(“Este es el dato nombre: %s”, variablecharnombre);

Si tuviéramos que pintar una ficha de datos con 15 variables, realizar esto sería bastante tedioso. Para mejorar esta situación podemos implementar una rutina (función) que realice estos pasos. La función podría tener este aspecto:

Void TxtPinta (int Fila , int Columna, int Tinta, int Papel, char Dato[80]);
{
     gotoxy(Columna, Fila);
//Aquí pondríamos un control de Papel Brillante(1)
textcolor (Tinta);
textbackground (Papel);
cprintf(“%s”, Dato);
}

De manera que en nuestro programa solo tendríamos que escribir:

TxtPinta(20, 10, LIGHTGREEN, RED, MyTexto);

Como se aprecia, esto es mucho más rápido y más legible a la hora de revisar el código fuente.

Adicionalmente, si queremos que el fondo sea brillante, por ejemplo pintar con Tinta GRANATE sobre Papel ROJO,  nuestra rutina debería incorporar el siguiente control:

If (Papel > 7) Tinta=Tinta+128; //(1)

Ejemplo completo:

#include<conio.h>
#include<stdio.h>
#include<string.h>

//==============================================================
// Definimos los Colores
//==============================================================
#define NEGRO        0
#define AZUL         1
#define VERDE        2
#define CYAN         3
#define GRANATE      4
#define MORADO       5
#define MARRON       6
#define BLANCO       7
#define GRIS         8
#define AZULB        9
#define VERDEB       10
#define CYANB        11
#define ROJO         12
#define LILA         13
#define AMARILLO     14
#define BLANCOB      15
#define BRILLO       128

//==============================================================
// Función Texto Pinta
//==============================================================
void TxtPinta (int Fila, int Columna, int Tinta, int Papel, char Txt[80])
{
gotoxy (Columna, Fila);
     if (Papel>7) Tinta=Tinta+BRILLO;
textcolor(Tinta);
textbackground(Papel);
cprintf(Txt);
}
//==============================================================
// Programa Principal
//==============================================================
void main()
{
int Fila, Columna, Tinta, Papel;
char Text[80];
char OtroText[1][80];
Fila=3;
Columna=20;
Papel=AZUL;          //Azul oscuro
Tinta=CYANB;         //Azul claro brillante

strcpy(Text," Prueba FUNCION TxtPinta ");
TxtPinta (Fila, Columna, Tinta, Papel, Text);

strcpy(OtroText[0]," Tabla0 FUNCION TxtPinta ");
TxtPinta (Fila+2, Columna, Tinta, Papel, OtroText[0]);

strcpy(OtroText[1]," Tabla1 FUNCION TxtPinta ");
TxtPinta (Fila+3, Columna, Tinta, Papel, OtroText[1]);

TxtPinta (Fila++, Columna++, GRANATE, ROJO, “Prueba de TxtPinta”);

getch();
}
//==============================================================
// FIN Programa Principal
//==============================================================

Esta función será muy útil en el 99,99% de los casos que queramos imprimir texto en pantalla. Como habréis observado está limitada a textos de 80 caracteres de longitud. Queda para los más avezados modificar la rutina para que pueda imprimir textos más largos.

Si os ha gustado suscribíos a mi canal y compartid esta entrada.

Gracias a todos.

¡¡Hasta la semana que viene!!

Descarga borland:

http://adf.ly/M2R8f

/* lo que yo hago ___________________________*/ /*___________________________________________________________*/