Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   C++ Builder (https://www.clubdelphi.com/foros/forumdisplay.php?f=13)
-   -   ¿Margen en celdas de TStringGrid? (https://www.clubdelphi.com/foros/showthread.php?t=86413)

aguml 05-08-2014 17:07:05

¿Margen en celdas de TStringGrid?
 
Buenas amigos, sigo mejorando el juego de las tablas y ahora le he añadido un ranking y todo va correcto pero me gustaria crear un pequeño margen para que cuando alineo a la derecha los numeros no llegue justo al filo sino que quede un poquitin de espacio a la derecha.
Esto tengo hecho:
Código:

void __fastcall TFormRanking::StringGridRankingDrawCell(TObject *Sender,
      int ACol, int ARow, TRect &Rect, TGridDrawState State)
{
        char *cadena;
        cadena = StringGridRanking->Cells[ACol][ARow].c_str();

        if (State.Contains(gdFixed))
        {
                StringGridRanking->Canvas->Brush->Color = clBtnFace;
                StringGridRanking->Canvas->Font->Color = clWindowText;
                StringGridRanking->Canvas->FillRect(Rect);

                HDC dc = StringGridRanking->Canvas->Handle;
                DrawText(dc, cadena, strlen(cadena), &Rect, DT_CENTER | DT_VCENTER | DT_SINGLELINE );
        }
        else if(State.Contains(gdSelected)) //if is selected use the clAqua color
        {
                StringGridRanking->Canvas->Brush->Color = clWindow;
                StringGridRanking->Canvas->Font->Color = clWindowText;
                StringGridRanking->Canvas->FillRect(Rect);

                HDC dc = StringGridRanking->Canvas->Handle;
                if(ACol == 1)
                        DrawText(dc, cadena, strlen(cadena), &Rect, DT_CENTER | DT_VCENTER | DT_SINGLELINE );
                else
                        DrawText(dc, cadena, strlen(cadena), &Rect, DT_RIGHT | DT_VCENTER | DT_SINGLELINE );
        }
        else if (ARow %2 == 0)
        {
                StringGridRanking->Canvas->Brush->Color = clSilver;
                StringGridRanking->Canvas->Font->Color = clWindowText;
                StringGridRanking->Canvas->FillRect(Rect);

                HDC dc = StringGridRanking->Canvas->Handle;
                if(ACol == 1)
                        DrawText(dc, cadena, strlen(cadena), &Rect, DT_CENTER | DT_VCENTER | DT_SINGLELINE );
                else
                        DrawText(dc, cadena, strlen(cadena), &Rect, DT_RIGHT | DT_VCENTER | DT_SINGLELINE );
        }
        else
        {
                StringGridRanking->Canvas->Brush->Color = StringGridRanking->Color;
                StringGridRanking->Canvas->Font->Color = StringGridRanking->Font->Color;
                StringGridRanking->Canvas->FillRect(Rect);

                HDC dc = StringGridRanking->Canvas->Handle;
                if(ACol == 1)
                        DrawText(dc, cadena, strlen(cadena), &Rect, DT_CENTER | DT_VCENTER | DT_SINGLELINE );
                else
                        DrawText(dc, cadena, strlen(cadena), &Rect, DT_RIGHT | DT_VCENTER | DT_SINGLELINE );
        }
}

¿Como puedo hacer eso?

aguml 05-08-2014 18:31:29

Al final lo he solucionado concatenando un espacio tras cada cadena que quiero alinear a la derecha. De todos modos si hay algun modo mejor pues me quedo a la espera de sus sugerencias.

ecfisa 05-08-2014 21:20:39

Hola aguml.

A mi tampoco se me ocurre otro medio mas sencillo que agregar un espacio al final. Pero si me permites, yo restructuraría el código de este modo:
Código:

void __fastcall TFormRanking::StringGridRankingDrawCell(TObject *Sender, int ACol,
      int ARow, TRect &Rect, TGridDrawState State)
{
  TStringGrid *SG = static_cast<TStringGrid*>((TStringGrid*)(Sender));
  String cad = SG->Cells[ACol][ARow];
  HDC dc = StringGrid1->Canvas->Handle;
  register int Flags = (ACol == 1 ? DT_CENTER | DT_VCENTER | DT_SINGLELINE :
                        DT_RIGHT | DT_VCENTER | DT_SINGLELINE);

  cad += (ACol > 1 ? " " : "");
  if (State.Contains(gdFixed)) {
    SG->Canvas->Brush->Color = clBtnFace;
    SG->Canvas->Font->Color = clWindowText;
    SG->Canvas->FillRect(Rect);
    DrawText(dc, cad.c_str(), cad.Length(), &Rect, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
  }
  else if(State.Contains(gdSelected)) {
    SG->Canvas->Brush->Color = clAqua;
    SG->Canvas->Font->Color = clWindowText;
    SG->Canvas->FillRect(Rect);
    DrawText(dc, cad.c_str(), cad.Length(), &Rect, Flags);
  }
  else {
    if (ARow % 2 == 0){
      SG->Canvas->Brush->Color = clSilver;
      SG->Canvas->Font->Color = clWindowText;
    }
    else {
      SG->Canvas->Brush->Color = SG->Color;
      SG->Canvas->Font->Color = SG->Font->Color;
    }
    SG->Canvas->FillRect(Rect);
    DrawText(dc, cad.c_str(), cad.Length(), &Rect, Flags);
  }
}

Saludos :)

aguml 06-08-2014 00:06:59

¿podrias explicarme que haces aqui?
Código:

register int Flags = (ACol == 1 ? DT_CENTER | DT_VCENTER | DT_SINGLELINE :
                      DT_RIGHT | DT_VCENTER | DT_SINGLELINE);
cad += (ACol > 1 ? " " : "");

Creo recordar que eso es igual que un if...else pero me pierdo con eso ¿podrias explicarme para entenderlo? ¿y que es register? Es que como pones "register int" pues no me suena ese tipo.

ecfisa 06-08-2014 00:45:23

Hola aguml.

El símbolo ? es el operador ternario de C y C++, y funciona de este modo:
Cita:

una_condición ? verdadero : falso
Ejemplos:
Código:

#include <iostream>

using namespace std;

#define MAX(a, b) ((a) > (b) ? (a) : (b))

char *MinMayEqu(const int a, const int b)
{
  return (a < b) ? "menor" : ((a > b) ? "mayor" : "igual");
}

int main()
{
  int a = 8, b = 7;
  cout << MAX(a,b) << endl;
  cout << a << " es " << MinMayEqu(a,b) << " a " << b;
  cin.get();
  return 0;
}

En tanto que la palabra reservada register, es un especificador del tipo de almacenamiento que debería usarse.
Le indica al compilador que, de ser posible, en lugar del stack utilice los registros del procesador para guardar los valores generando así un código mas rápido. (Solo se aplica a variables automáticas y parámetros)

Saludos :)

aguml 06-08-2014 00:56:05

Lo he probado y he tenido que modificarlo un poco ya que mi codigo tambien fue modificado un poco para hacer lo que yo queria realmente. Asi ha quedado pero tiene un problemilla:

Código:

void __fastcall TFormRanking::StringGridRankingDrawCell(TObject *Sender, int ACol,
      int ARow, TRect &Rect, TGridDrawState State)
{
  TStringGrid *SG = static_cast<TStringGrid*>((TStringGrid*)(Sender));
  String cad = SG->Cells[ACol][ARow];
  HDC dc = StringGridRanking->Canvas->Handle;
  register int Flags = (ACol == 1 || State.Contains(gdFixed) ? DT_CENTER | DT_VCENTER | DT_SINGLELINE :
                        DT_RIGHT | DT_VCENTER | DT_SINGLELINE);

  cad += (ACol != 1 && ARow > 0 ? " " : "");
  if (State.Contains(gdFixed)) {
    SG->Canvas->Brush->Color = clBtnFace;
    SG->Canvas->Font->Color = clWindowText;
    SG->Canvas->FillRect(Rect);
    DrawText(dc, cad.c_str(), cad.Length(), &Rect, Flags);
  }
  else if(State.Contains(gdSelected)) {
    SG->Canvas->Brush->Color = clWindow;
    SG->Canvas->Font->Color = clWindowText;
    SG->Canvas->FillRect(Rect);
    HDC dc = StringGridRanking->Canvas->Handle; //No se porque pero si no pongo esta linea no aparece el texto de la celda seleccionada
    DrawText(dc, cad.c_str(), cad.Length(), &Rect, Flags );
  }
  else {
    if (ARow % 2 == 0){
      SG->Canvas->Brush->Color = clSilver;
      SG->Canvas->Font->Color = clWindowText;
    }
    else {
      SG->Canvas->Brush->Color = SG->Color;
      SG->Canvas->Font->Color = SG->Font->Color;
    }
    SG->Canvas->FillRect(Rect);
    DrawText(dc, cad.c_str(), cad.Length(), &Rect, Flags );
  }
}

Ahi tienes el comentario de que tengo que hacer para que funcione y es algo raro ya que eso mismo se hace al principio pero no se porque tengo que volverlo a hacer.

ecfisa 06-08-2014 03:30:47

Hola aguml.

Acabo de probar el codigo que publicaste y me funciona bién, lo que si veo es que me quedó un detalle de la prueba, cambiar la siguiente línea,
Código:

HDC dc = StringGrid1->Canvas->Handle;
pero eso hace más reusable la rutina, no es solución al comportamiento que mencionas. No sé que puede estar pasando aunque supongo que se debe a una cuestión de superposición de colores ...

Te pongo el código completo de mi prueba (que funciona correctamente) para que puedas controlar
con el tuyo.
Código:

/* darle algunos valores a la grilla */
void __fastcall TForm1::FormCreate(TObject *Sender)
{
  StringGrid1->Options << TGridOption(goEditing);
  for (register int c = 0; c < StringGrid1->ColCount; c++)
    for (register int r = 0; r < StringGrid1->RowCount; r++)
      StringGrid1->Cells[c][r] = IntToStr(c+r);
}

/* organizar la presentación */
void __fastcall TForm1::StringGrid1DrawCell(TObject *Sender, int ACol,
      int ARow, TRect &Rect, TGridDrawState State)
{
  TStringGrid *SG = static_cast<TStringGrid*>((TStringGrid*)(Sender));
  String cad = SG->Cells[ACol][ARow];
  HDC dc = SG->Canvas->Handle;    // <<<< --- Cambio
  register int Flags = (ACol == 1 ? DT_CENTER | DT_VCENTER | DT_SINGLELINE :
                        DT_RIGHT | DT_VCENTER | DT_SINGLELINE);

  cad += (ACol > 1 ? " " : "");
  if (State.Contains(gdFixed)) {
    SG->Canvas->Brush->Color = clBtnFace;
    SG->Canvas->Font->Color = clWindowText;
    SG->Canvas->FillRect(Rect);
    DrawText(dc, cad.c_str(), cad.Length(), &Rect, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
  }
  else if(State.Contains(gdSelected)) {
    SG->Canvas->Brush->Color = clAqua;
    SG->Canvas->Font->Color = clWindowText;
    SG->Canvas->FillRect(Rect);
    DrawText(dc, cad.c_str(), cad.Length(), &Rect, Flags);
  }
  else {
    if (ARow % 2 == 0){
      SG->Canvas->Brush->Color = clSilver;
      SG->Canvas->Font->Color = clWindowText;
    }
    else {
      SG->Canvas->Brush->Color = SG->Color;
      SG->Canvas->Font->Color = SG->Font->Color;
    }
    SG->Canvas->FillRect(Rect);
    DrawText(dc, cad.c_str(), cad.Length(), &Rect, Flags);
  }
}

Si tenes alguna dificultad, no dudes en avisame y te adjunto los fuentes.

Saludos :)

aguml 06-08-2014 08:31:36

Amigo al final asi me ha quedado todo lo que gestiona el ranking:

Este botón está en el form principal y es el que se usa para terminar el juego. Si la puntuacion es mas alta que la de alguna otra del ranking nos mostrará otra ventana que nos pregunta nuestro nombre y guarda los datos en el ranking. Si la puntuacion es igual a alguna del ranking se usa el numero de aciertos para ordenarlo:
Código:

void __fastcall TFormPrincipal::ButtonPararClick(TObject *Sender)
{
        //Desactivo el timer
        Timer1->Enabled = false;

        //Activo el boton Comenzar
        ButtonComenzar->Enabled = true;

        //Desactivo el Edit donde se introducen los resultados
        EditResultado->Enabled = false;

        //Desactivo el boton Comprobar
        ButtonComprobar->Enabled = false;

        //Desactivo el boton Parar
        ButtonParar->Enabled = false;

        //Inicializo la cuenta atras
        LabelCuentaAtras->Caption = TrackBarRangoTimer->Position;
        LabelCuentaAtras->Font->Color = clGreen;
        LabelCuentaAtras->Update();

        //Leer y actualizar ranking
        int hFile = FileOpen("Ranking.bin",fmOpenReadWrite);

        struct
        {
                int pos;
                char nombre[10];
                int aciertos;
                int puntuacion;
        }ranking[10], nuevoRanking[10];

        //Limpio ambas estructuras
        memset(ranking,0,sizeof(ranking));
        memset(nuevoRanking,0,sizeof(nuevoRanking));

        if(hFile == -1) //Si no existe el archivo de ranking
        {
                hFile=FileCreate("Ranking.bin"); //lo creo

                //Inicializado del archivo de ranking
                for(int i=0;i<10;i++)
                {
                        ranking[i].pos = i+1;
                        strcpy(ranking[i].nombre, "Agustin");
                        ranking[i].aciertos = 100-(i*10);
                        ranking[i].puntuacion = 10000-(i*1000);

                }
                FileSeek(hFile,0,0);
                FileWrite(hFile,ranking,sizeof(ranking));
                //fin del inicializado del ranking
        }

        //Lectura del ranking
        FileSeek(hFile,0,0);
        FileRead(hFile,ranking,sizeof(ranking));

        bool changed = false; //bandera que uso para saber si ya inserté el registro en el ranking

        //En el siguiente bucle recorro todo el ranking y si tengo que insertar la partida finalizada lo hago
        //Cuando inserte la nueva linea no incremento el indice del ranking para asi seguir leyendo por donde me quedé
        for(int i=0,j=0;i<10;i++)
        {
                if(ranking[i].puntuacion > EditPuntos->Text.ToDouble() || changed == true)
                { //Si la puntuacion de la posicion actual es mayor que la obtenida o ya fue insertada la nueva puntuacion...
                        nuevoRanking[i] = ranking[j]; //Copio los datos de esa linea del ranking en el nuevo ranking
                        j++; //Incremento el indice del ranking

                        //Voy incrementando la posicion
                        if(i > 0)
                        {
                                nuevoRanking[i].pos = nuevoRanking[i-1].pos + 1;
                        }
                }
                else if(ranking[j].puntuacion == EditPuntos->Text.ToDouble())
                { //Si la puntuacion del ranking es igual a la obtenida...
                        if(ranking[j].aciertos < EditAciertos->Text.ToDouble())
                        { //Si el numero de aciertos de la posicion actual del ranking es menor que los obtenidos

                                FormInsertName->ShowModal(); //Pregunto el nombre del jugador
                                nuevoRanking[i].pos = ranking[j].pos; //Inserto la posicion
                                strncpy(nuevoRanking[i].nombre, FormInsertName->EditName->Text.c_str(),10); //Inserto el nuevo nombre
                                nuevoRanking[i].aciertos = EditAciertos->Text.ToDouble(); //Inserto el nuevo numero de aciertos
                                nuevoRanking[i].puntuacion = EditPuntos->Text.ToDouble(); //Inserto la nueva puntuacion
                                changed = true; //Indico que ya se ha insertado la nueva linea
                        }
                }
                else
                {
                        FormInsertName->ShowModal(); //Pregunto el nombre del jugador
                        nuevoRanking[i].pos = ranking[j].pos; //Inserto la posicion
                        strncpy(nuevoRanking[i].nombre, FormInsertName->EditName->Text.c_str(),10); //Inserto el nuevo nombre
                        nuevoRanking[i].aciertos = EditAciertos->Text.ToDouble(); //Inserto el nuevo numero de aciertos
                        nuevoRanking[i].puntuacion = EditPuntos->Text.ToDouble(); //Inserto la la nueva puntuacion
                        changed = true; //Indico que ya se ha insertado la nueva linea
                }
        }

        //Si hubo cambio en el ranking actualizo el archivo
        if(changed == true)
        {
                FileSeek(hFile,0,0);
                FileWrite(hFile,nuevoRanking,sizeof(nuevoRanking));

                //Cierro el archivo de ranking
                FileClose(hFile);

                //Muestro el nuevo ranking
                FormRanking->ShowModal();
        }
        else
        {
                //Cierro el archivo de ranking
                FileClose(hFile);
        }
}
//---------------------------------------------------------------------------

Esto es para que se muestre el ranking correctamente:
Código:

void __fastcall TFormRanking::FormShow(TObject *Sender)
{
        //Posiciono la ventana centrada
        Left = (Screen->Width - Width)/2;
        Top  = (Screen->Height - Height)/2;

        //Abro el archivo donde está el ranking
        int hFile = FileOpen("Ranking.bin",fmOpenReadWrite);

        //Estructura que contendrá el ranking
        struct
        {
                int pos;
                char nombre[10];
                int aciertos;
                int puntuacion;
        }ranking[10];

        //Limpio la estructura
        memset(ranking,0,sizeof(ranking));

        if(hFile == -1) //Si no existe el archivo de ranking
        {
                hFile=FileCreate("Ranking.bin"); //lo creo

                //Inicializado del archivo de ranking
                for(int i=0;i<10;i++)
                {
                        ranking[i].pos = i+1;
                        strcpy(ranking[i].nombre, "Agustin");
                        ranking[i].aciertos = 100-(i*10);
                        ranking[i].puntuacion = 10000-(i*1000);

                }
                FileSeek(hFile,0,0); //Me posiciono al inicio del archivo
                FileWrite(hFile,ranking,sizeof(ranking)); //Guardo el ranking en el archivo
                //fin del inicializado del ranking
        }

        //Lectura del ranking
        FileSeek(hFile,0,0); //Me posiciono al inicio del archivo
        FileRead(hFile,ranking,sizeof(ranking)); //Leo el contenido del archivo y lo guardo en la estructura
        FileClose(hFile); //Cierro el archivo

        //Ajusto los anchos de las columnas
        StringGridRanking->ColWidths[0]=110;
        StringGridRanking->ColWidths[1]=175;
        StringGridRanking->ColWidths[2]=125;
        StringGridRanking->ColWidths[3]=150;

        //Pongo los titulos a la tabla
        StringGridRanking->Rows[0]->Strings[0] = "Posición";
        StringGridRanking->Rows[0]->Strings[1] = "Nombre";
        StringGridRanking->Rows[0]->Strings[2] = "Aciertos";
        StringGridRanking->Rows[0]->Strings[3] = "Puntuación";

        //Relleno el StringGrid que mostrará el ranking
        for(int row = 1; row < 11; row++)
        {
                StringGridRanking->Rows[row]->Strings[0] = AnsiString(ranking[row-1].pos) + " ";
                StringGridRanking->Rows[row]->Strings[1] = ranking[row-1].nombre;
                StringGridRanking->Rows[row]->Strings[2] = AnsiString(ranking[row-1].aciertos) + " ";
                StringGridRanking->Rows[row]->Strings[3] = AnsiString(ranking[row-1].puntuacion) + " ";
        }
}
//---------------------------------------------------------------------------

void __fastcall TFormRanking::StringGridRankingDrawCell(TObject *Sender, int ACol,
      int ARow, TRect &Rect, TGridDrawState State)
{
        TStringGrid *SG = static_cast<TStringGrid*>((TStringGrid*)(Sender));
        String cad = SG->Cells[ACol][ARow];
        HDC dc = SG->Canvas->Handle;

        //Asignamos a Flags los flags deseados segun la posicion de la celda
        //Esto equivale a:
        /*register int Flags;
        if(ACol == 1 || State.Contains(gdFixed))
                Flags = DT_CENTER | DT_VCENTER | DT_SINGLELINE;
        else
                Flags = DT_RIGHT | DT_VCENTER | DT_SINGLELINE;
        */

        register int Flags = (ACol == 1 || State.Contains(gdFixed) ? DT_CENTER | DT_VCENTER | DT_SINGLELINE :
                              DT_RIGHT | DT_VCENTER | DT_SINGLELINE);

        //Aqui se añade un espacio al final de la cadena siempre que no sea un titulo y no sea de la columna 1
        //Esto equivale a:
        /*if(ACol != 1 && ARow > 0)
                cad += " ";
        */

        cad += (ACol != 1 && ARow > 0 ? " " : "");

        if (State.Contains(gdFixed)) {
                SG->Canvas->Brush->Color = clBtnFace;
                SG->Canvas->Font->Color = clWindowText;
                SG->Canvas->FillRect(Rect);
                DrawText(dc, cad.c_str(), cad.Length(), &Rect, Flags);
        }
        else if(State.Contains(gdSelected)) {
                SG->Canvas->Brush->Color = clWindow;
                SG->Canvas->Font->Color = clWindowText;
                SG->Canvas->FillRect(Rect);
                HDC dc = StringGridRanking->Canvas->Handle; //No se porque pero aqui tengo que repetir esta linea para que funcione en este caso
                DrawText(dc, cad.c_str(), cad.Length(), &Rect, Flags);
        }
        else {
                if (ARow % 2 == 0){
                        SG->Canvas->Brush->Color = clSilver;
                        SG->Canvas->Font->Color = clWindowText;
                }
                else {
                        SG->Canvas->Brush->Color = SG->Color;
                        SG->Canvas->Font->Color = SG->Font->Color;
                }
                SG->Canvas->FillRect(Rect);
                DrawText(dc, cad.c_str(), cad.Length(), &Rect, Flags);
        }
}
//---------------------------------------------------------------------------

Funciona correctamente pero me gustaria que le echases un vistazo para ver si ves algo de codigo redundante que se pueda mejorar. ¡Gracias por todo!

ecfisa 07-08-2014 07:35:08

Hola aguml.

No probé el código pero no veo nada fuera de lugar (por otro lado comentas que funciona correctamente).
Lo que sí creo, es que aprovechar la VCL mediante TFileStream te podría reducir y simplificar un poco el código de tratamiento del archivo, pero queda a tu critero...

Te hice un ejemplo en el que intervienen la lectura y escritura ya que es lo que hace a lo que te sugiero mas arriba:
Código:

...
#define FILE_NAME  "ranking.bin"
#define MAX_ELEM 10

struct {
  int pos;
  char nombre[30];
  int aciertos;
  int puntuacion;
} ranking[MAX_ELEM];

void __fastcall TForm1::FormCreate(TObject *Sender)
{
  TStringGrid *SG = static_cast<TStringGrid*>(StringGrid1);
  DWORD openflag = FileExists(FILE_NAME) ? fmOpenReadWrite : fmCreate;
  TFileStream *FS = new TFileStream(FILE_NAME, openflag);

  // ajustar columnas, poner títulos
  SG->ColWidths[0] = 110;
  SG->ColWidths[1] = 175;
  SG->ColWidths[2] = 125;
  SG->ColWidths[3] = 150;
  SG->Rows[0]->DelimitedText = ",Posicion,Nombre,Aciertos,Puntuacion";

  // limpiar struct
  ZeroMemory(&ranking, 0);

  if (openflag == fmCreate) { // el archivo no existia
    for(register int i=0; i < MAX_ELEM; i++) {
      ranking[i].pos = i+1;
      strcpy(ranking[i].nombre, "Agustin");
      ranking[i].aciertos = 100-(i*10);
      ranking[i].puntuacion = 10000-(i*1000);
    }
    FS->Write(&ranking, sizeof(ranking));  // guardar arreglo
  }
  else  // el archivo existia
    FS->Read(&ranking, sizeof(ranking));  // leer

  // struct a StringGrid
  for(register int i=0; i< MAX_ELEM; i++) {
    SG->Rows[i+1]->Strings[0]= i+1;
    SG->Rows[i+1]->Strings[1]= String(ranking[i].pos) + " ";
    SG->Rows[i+1]->Strings[2]= ranking[i].nombre;
    SG->Rows[i+1]->Strings[3]= String(ranking[i].aciertos) + " ";
    SG->Rows[i+1]->Strings[4]= String(ranking[i].puntuacion) + " ";
  }
  delete FS;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
  TStringGrid *SG = static_cast<TStringGrid*>(StringGrid1);
  TFileStream *FS = new TFileStream(FILE_NAME, fmOpenWrite);

  // StringGrid a struct
  for(register int i= 0; i < MAX_ELEM; i++) {
    ranking[i].pos = StrToIntDef(Trim(SG->Rows[i+1]->Strings[1]), 0);
    strcpy(ranking[i].nombre,SG->Rows[i+1]->Strings[2].c_str());
    ranking[i].aciertos = StrToIntDef(Trim(SG->Rows[i+1]->Strings[3]), 0);
    ranking[i].puntuacion = StrToIntDef(Trim(SG->Rows[i+1]->Strings[4]), 0);
  }
  // guardar arreglo
  FS->Write(&ranking, sizeof(ranking));
 delete FS;
}

El código verifica que el archivo exista al crearse el form, de ser así lee los datos, en caso contrario, inicializa el arreglo de estructuras con los valores por omisión y lo guarda, por último muestra los valores en StringGrid.

Y para finalizar la muestra del uso de TFileStream, al salir se almacenan los valores de las celdas del StringGrid (modificados o nó) en el archivo.

Saludos :)


La franja horaria es GMT +2. Ahora son las 09:01:16.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi