• Viernes 8 de Noviembre de 2024, 19:56

Autor Tema:  ¿¿que Ocurre Con Text.c_str() De Un Tedit???  (Leído 3809 veces)

garth

  • Nuevo Miembro
  • *
  • Mensajes: 11
    • Ver Perfil
¿¿que Ocurre Con Text.c_str() De Un Tedit???
« en: Domingo 2 de Mayo de 2004, 23:41 »
0
en una rutina hago esto:

void __fastcall TForm3::bufferChange(TObject *Sender)
{
  buf=new char[buffer->MaxLength];

  buf=buffer->Text.c_str();
}

para tener en 'buf' lo que se ha introducido en el TEdit 'buffer'. Lo hace bien pero el ultimo caracter se lo come. Si MaxLength vale 5 y escribo "holas", buf va a contener: "hola".

Alguien me puede decir como arreglar esto. ¿Es un fallo del c++ builder o soy yo que soy un maleta?

Gracias.

FordFarlaine

  • Nuevo Miembro
  • *
  • Mensajes: 23
    • Ver Perfil
Re: ¿¿que Ocurre Con Text.c_str() De Un Tedit???
« Respuesta #1 en: Lunes 3 de Mayo de 2004, 14:29 »
0
Bueno, esto esta un poco regular:
Primero, la memoria reservada con el operador 'new' no se libera automaticamente, la tienes que liberar con el operador 'delete', y aqui cada vez que ejecute la funcion haces una reserva de memoria que despues en algun sitio tendras que liberar. ¿Lo haces?
Segundo, suponiendo que despues la liberas en cualquier otro sitio, no estara bien de todas maneras ya que buf, entiendo que es un puntero a una cadena de caracteres, y primero reservas memoria para el y lo direccionas a esa reserva de memoria. Pero a continuacion lo vuelves a redireccionar a la direccion que te devuelve el operador c_str() de la clase AnsiString. Con lo que la memoria queda reservada pero inutilmente, ya que pierdes la direccion donde la tenias.

Soluciones:
 Primero, no se para que quieres el buffer auxiliar buf, pero si lo que quieres es tener una cadena de caracteres que en todo momento contenga lo que hay en el TEdit, ya la tienes en el propio control, y su direccion de memoria te la devuelve el operador c_str().

Si de todas maneras quieres tener en una variable (por algo que no logro entender), la direccion de lo que hay escrito. Entonces elimina la primera linea, no reservando memoria y limitandote a hacer la asignacion.

Y por ultimo, si quieres tener en otra cadena lo que en un momento dado habia escrito en el TEdit, tienes que hacer una copia de la memoria y no una asignacion de direccion. ¿Como? Asignas el valor NULL por defecto al puntero buf (por ejemplo en el oncreate del TEdit). Y aqui liberas el valor anterior del buf, y le reservas el nuevo valor para el tamaño que necesites, y acontinuacion haces una copia de memoria.

.
.
buf=NULL;
.
.

void __fastcall TForm3::bufferChange(TObject *Sender)
{
....
  if(buf!=NULL) delete [] buf;
  buf=new char[buffer->Text.Length()+1];   // el mas uno es para el caracter 0
                                                               // que termina el string
  memcpy(buf,buffer->Text.c_str(),buffer->Text.Length()+1); // copia la memoria
}
El MenosMola

garth

  • Nuevo Miembro
  • *
  • Mensajes: 11
    • Ver Perfil
Re: ¿¿que Ocurre Con Text.c_str() De Un Tedit???
« Respuesta #2 en: Lunes 3 de Mayo de 2004, 18:11 »
0
A ver FordFarlaine; me has abierto mucho los ojos. Si, soy un mulo programando. Te explico por encima a ver con que solucion me quedo:

Estoy haciendo un simulador del puerto PCI, y en buf quiero meter lo que el usuario escriba en el TEdit que va a ser lo que se "escriba" en la memoria reservada para un dispositivo pci. Por lo tanto lo quiero tener como un array de caracteres siempre accesible desde otro Form que es el que simula. buf lo tengo declarado como variable del Form. A 'buf' necesito acceder por posiciones y creo que con el ansistring del TEdit no obtengo solucion a lo que quiero no?

a ver si esto te lo ha aclarado.

Muchisimas gracias.

FordFarlaine

  • Nuevo Miembro
  • *
  • Mensajes: 23
    • Ver Perfil
Re: ¿¿que Ocurre Con Text.c_str() De Un Tedit???
« Respuesta #3 en: Martes 4 de Mayo de 2004, 10:56 »
0
Bueno, si te he entendido, el buf lo tienes declarado como variable miembro de la Form que utilizas como 'PCI', y no de la que tiene el TEdit.
Pues bien, si esto es así, yo elegiria una de las dos siguientes opciones:

Primera: la ultima que te dije en el otro post, pero colocando el buf=NULL, en el constructor de la Form 'PCI'. Teniendo en cuenta que tienes que hacer en el ".cpp" de la Form que contiene el TEdit un  #include con el ".h" de la form 'PCI' (cosa que me imagino ya hiciste).

Segunda: Si 'con acceder por posiciones' te refieres a poder acceder independientemente, a cada una de las letras del array. Puedes hacerlo desde la otra form, siempre que la Form que contiene el TEdit no este destruida, directamente con el TEdit, mediante dos maneras:
      1º- Con el famoso c_str(). esto de devuelve la direccion donde comienza el
            array de caracteres como si fuera 'Ansi C', asi el primer elemento lo
            obtienes con " (Form1->buffer->Text.c_str())[0] ", los demas
            sustituyendo el
  • por el elemento en cuestion.

      2º- Colocando el operador [] sobre el ansi string te devuelve directamente el
            caracter, ejemplo para el primer elemento " (Form1->buffer->Text)[1] "
            (notar que de una manera el primer elemento es el 0, y de la otra el 1)
   Para esta soluciontambien tendrias que #incluir en la Form 'PCI' el ".h" de la Form1, o como llames a la que contiene el TEdit
El MenosMola

garth

  • Nuevo Miembro
  • *
  • Mensajes: 11
    • Ver Perfil
Re: ¿¿que Ocurre Con Text.c_str() De Un Tedit???
« Respuesta #4 en: Miércoles 5 de Mayo de 2004, 00:43 »
0
Muchas gracias Ford Farlaine! ;)

creo ke escogere la segunda. Ademas ya tenia #incluido :P el ".h" de los demas forms.

Una preguntita mas. Al simularlo, saco por pantalla el cronograma de estados por los que atraviesa el dispositivo PCI representando sus señales; eso lo hago utilizanfo el canvas. Ahora bien, cuando desplazo la barra de desplazamiento hacia la derecha para ver el resto de la simulacion, lo que se corre hacia la izquierda, se borra, desaparece. Hay alguna forma de refrescarlo para que no se pierda.

P.D.: yo he hecho a lo bruto que simulase de nuevo por medio de una funcion FormPaint en el evento OnPaint (el problema es que la simulacion no tiene por que ser la misma, intervienen variables "ramdom's").

Gracias por aguantarme. :D
Saludos.

FordFarlaine

  • Nuevo Miembro
  • *
  • Mensajes: 23
    • Ver Perfil
Re: ¿¿que Ocurre Con Text.c_str() De Un Tedit???
« Respuesta #5 en: Miércoles 5 de Mayo de 2004, 09:34 »
0
No se muy bien que es lo que muestras (¿cromograma?), pero entiendo que lo que haces es mostrar un grafico por pantalla, y que este tiene una cierta aleatoriedad.
Bueno, el problema lo tienes en que el grafico no te cabe en toda la pantalla y quieres usar el scroll para ver lo que no muestras.
Bueno yo usaria dos posibles soluciones.

Primera. Me generaria un Bitmap con todo el grafico y despues en la funcion que te creaste de pintado, teniendo en cuenta la posicion del scroll mostraria una parte u otra del bitmap haciendo una copia de esta parte en el canvas.

Segunda. En lugar de pintar en el canvas de la pantalla, crearia un TImage en la pantalla de tamaño igual al grafico a mostrar, y haria el grafico sobre el canvas de este TImage (la propia pantalla gestionara lo que muestra, ya que no tienes que regenerar el bitmap, porque esta guardado en objeto TImage).
     " Image1->Picture->Bitmap->Canvas "

PD. Si no necesitas un escalado perfecto del grafico, puedes mostrarlo en una sola pantalla utilizando las funciones 'Stretch' que redimensionan un grafico a un tamaño dado. (esto hay que hacerlo creandote el grafico en un bitmap independiente y usando las funciones stretch para copiarlo redimensionado a la pantalla)
Ejemplo.
      SetStretchBltMode(Form1->Canvas->Handle,COLORONCOLOR);
      StretchDIBits(Form1->Canvas->Handle,0,0,Form1->Width,Form1->Height,0,0,bitmapauxiliar->Width,bitmapauxiliar->Height,bitmapptr,&bmi,DIB_RGB_COLORS,SRCCOPY);

(mirar funciones del Windows SDK, en la ayuda de Builder)
El MenosMola

garth

  • Nuevo Miembro
  • *
  • Mensajes: 11
    • Ver Perfil
Re: ¿¿que Ocurre Con Text.c_str() De Un Tedit???
« Respuesta #6 en: Miércoles 5 de Mayo de 2004, 09:54 »
0
Hola de nuevo.
Yo lo he dibujado a traves de un paintBox: PaintBox1->Canvas, pero supongo que esto no refresca, no?

Entonces, a ver si lo entiendo, dices que si en vez de un paintbox lo dibujo a traves de una TImage se me refrescará el grafico siempre cuando mueva el scroll?

si es asi------> Forza TImage!!!

Gracias ti@.

FordFarlaine

  • Nuevo Miembro
  • *
  • Mensajes: 23
    • Ver Perfil
Re: ¿¿que Ocurre Con Text.c_str() De Un Tedit???
« Respuesta #7 en: Jueves 6 de Mayo de 2004, 09:19 »
0
Si, eso es. Porque el timage, almacena el bitmap en una de sus variables miembro, y el se preocupa de la gestion de lo mostrado en pantalla.
Mientras los canvas son solo el lienzo que muestra en ese momento en pantalla, con lo que si los quitas no se refrescan porque no estan guardados en ningun sitio.

Ciao
El MenosMola

garth

  • Nuevo Miembro
  • *
  • Mensajes: 11
    • Ver Perfil
Re: ¿¿que Ocurre Con Text.c_str() De Un Tedit???
« Respuesta #8 en: Jueves 6 de Mayo de 2004, 18:48 »
0
wenasss.

Pues si...va de arte el TImage. Pero...yo el fondo lo quiero negro, y siempre sala blanco....aaaaaaaaaaaahh. Y no tiene la propiedad color. Siempre me pasa algo.
He intentao ponerlo transparente, pero le da igual...cuando pinta se pone en blanco.

Ves alguna solucion FordFarlaine?

gracias.

FordFarlaine

  • Nuevo Miembro
  • *
  • Mensajes: 23
    • Ver Perfil
Re: ¿¿que Ocurre Con Text.c_str() De Un Tedit???
« Respuesta #9 en: Lunes 10 de Mayo de 2004, 09:21 »
0
No se. Cuando hagas el grafico a pintar, antes rellena el fondo con un rectangulo negro del tamaño de la ventana  ...->canvas->Rectangle
El MenosMola

garth

  • Nuevo Miembro
  • *
  • Mensajes: 11
    • Ver Perfil
Re: ¿¿que Ocurre Con Text.c_str() De Un Tedit???
« Respuesta #10 en: Lunes 10 de Mayo de 2004, 10:21 »
0
Si, eso hice. Ya funciona de arte. Gracias!