Ir al contenido


Foto

Iconos en DBGRid distorsionado y aumentado


  • Por favor identifícate para responder
24 respuestas en este tema

#1 dooper

dooper

    Advanced Member

  • Miembros
  • PipPipPip
  • 298 mensajes

Escrito 14 mayo 2015 - 06:37

Sabe alguien porque al insertar un icono en dbgrid, este me aparece algo más agrandado y pixelado por su contorno que el original 16x16 .ico.

 

A ver si puedo poner un grafico del caso concreto, pero no se si es normal en estos casos, o es que hay posiblidad de modificarlo por medio de las propiedades del objeto.

 

Un saludo


  • 0

#2 dooper

dooper

    Advanced Member

  • Miembros
  • PipPipPip
  • 298 mensajes

Escrito 14 mayo 2015 - 02:35

Adjunto el un pantallazo del DBGrid para que veais el resultado totalmente desastroso. incluyo el icono original 16x16 .ico

Decir que en otros DBGrid que he visto estos iconos no se visualizaban mal. En este caso aparece más dimensionado que el original y dentado en su contorno.

 

Igualmente, vereis que marcando la opción de la fila se borra el contenido de la misma cuando pulso sobre ella. Nikolas me indico como activarla con la propiedad correspondiente, pues si elimino el icono, si hace su función la propiedad de activar la fila en azul, sino aparece eso que veis.

 

Algo decepcionado con la posibilidad de incluir iconos en los grillas, y su selección activa.

 

No se se habrá alguna solución,

Archivos adjuntos


  • 0

#3 escafandra

escafandra

    Advanced Member

  • Administrador
  • 4.107 mensajes
  • LocationMadrid - España

Escrito 14 mayo 2015 - 03:59

¿No estarás usando Strech?

Saludos.
  • 0

#4 dooper

dooper

    Advanced Member

  • Miembros
  • PipPipPip
  • 298 mensajes

Escrito 14 mayo 2015 - 11:39

Pues si te refires al procedimiento que creo que si Escafamdra, sí.

 

rocedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;
  DataCol: Integer; Column: TColumn; State: TGridDrawState);
var
  fixRect:TRect;
  bitmap : TBitmap;
  imgIndex, bmpwidth: Integer;
begin
    fixRect := Rect;
    if column.Field = Tabla.FieldByname('Edad') then  // compruebo si es la columna=edad para pintar.
    begin
      if  Tabla.FieldByname('Edad').AsInteger > 18 then
        imgIndex := 0
      else
        imgIndex := 1;
 
        bitmap := TBitmap.Create;
        try
          ImageList1.GetBitmap(imgIndex,bitmap);
          bmpWidth := (Rect.Bottom - Rect.Top);
          fixRect.Right := Rect.Left + bmpWidth;
          DBGrid1.Canvas.StretchDraw(fixRect,bitmap);
        finally
          bitmap.Free;
        end;
    
        fixRect := Rect;
        fixRect.Left := fixRect.Left + bmpWidth;
    end;
 
  DBGrid1.DefaultDrawColumnCell(fixRect,DataCol,Column,State); // ni idea que hace este procedimiento.
end;

 

Por eso puede ser? como puedo solventar el problema.

 

Un saludo.


  • 0

#5 escafandra

escafandra

    Advanced Member

  • Administrador
  • 4.107 mensajes
  • LocationMadrid - España

Escrito 15 mayo 2015 - 07:35

StretchDraw ajusta la imagen al espacio disponible, agrandando o reduciendola. Los resultados no siempre son buenos.

Utiliza 


delphi
  1. procedure Draw(X: Integer; Y: Integer; Graphic: TGraphic); overload;

Con una imagen del tamaño apropiado.

 

 

Saludos.


  • 0

#6 dooper

dooper

    Advanced Member

  • Miembros
  • PipPipPip
  • 298 mensajes

Escrito 15 mayo 2015 - 12:19

Gracias escafrandra, pero no consigo adecuar el codigo para que funcione correctamente al procedimiento de arriba indicado.

He cambiado StretchDraw por Draw

 

DBGrid1.Canvas.Draw(fixRect.Right, Bmpwidth,bitmap);

 

y he eliminado el

 

DBGrid1.DefaultDrawColumnCell(fixRect,DataCol,Column,State) y ahora si aparece a su tamaño original, estabas en lo correcto amigo!

 

pero se visualiza solo el icono de la fila1, los demás no salen. Aparte sigo con el dichoso error de no visualizar el contenido de las celdas cuando está activa la fila.

 

:sad:


  • 0

#7 dooper

dooper

    Advanced Member

  • Miembros
  • PipPipPip
  • 298 mensajes

Escrito 15 mayo 2015 - 03:00

Resuelto el problema del icono. me faltaba configurar el Draw con los parámetros correctos.

 

Sigo con el problema de fila seleccionada me oculta elcontenido del nombre y edad apareciendo solamente el icono, paso a la segunda fila seleccionada y aparecer el contenido del nombre y edad en la primera fila. Ni idea de porque.

 

Tambien tenía el mismo error enecumene que en la primera columna de la tabla si inserta un icono, el texto aparece alineado a la izquierda de la celda y el icono se sobrepone encima. He buscado alternativas para mover el texto y pinte el icono pirmeramente y el texto a continuación e imposible.

 

A ver si alguien puede dar alguna solución a estos escollos...

 

Gracias


  • 1

#8 escafandra

escafandra

    Advanced Member

  • Administrador
  • 4.107 mensajes
  • LocationMadrid - España

Escrito 15 mayo 2015 - 04:49

DBGrid1.DefaultDrawColumnCell(fixRect,DataCol,Column,State); // ni idea que hace este procedimiento.

Esa es la línea que llama al procedimiento "original" del DBGrid para pintar el la celda, pinta el texto. Si la eliminas, deja de aparecer el texto, con lo que tienes que pintarlo a mano con TextOut, Ten en cuenta que el texto has de desplazarlo a la derecha para que el icono y texto no se pisen.

 

Otra forma es no eliminarla, pero corregir el primer parámetro que recibe que es un TRect. Ese TRect debes ajustarlo desplazándolo a la derecha para que no se pisen texto e imagen:


delphi
  1. fixRect.Right := Rect.Left + bmpWidth;

bmpWidth debe ser como mínimo el ancho de la imagen de tu icono.

 

 

Saludos.


  • 0

#9 dooper

dooper

    Advanced Member

  • Miembros
  • PipPipPip
  • 298 mensajes

Escrito 16 mayo 2015 - 07:43

Eso hago escafandra, pero el codigo queda así, y no hay manera de que aparece primeramente el icono y luego el texto.
 
Además mira como la fila seleccionada no tiene valores, solo aparece el icono, cuando salgo de la fila seleccionada vuelven
aparecer. Mi intención es que funcione como debe funcionar un DBgrid con la fila seleccionada totalmente activa en color azul
y con los datos visibles, cosa que de momento es imposible de resolucionar por mi parte.
 
 

delphi
  1.  fixRect := Rect;
  2.  
  3.    if column.Field = Tabla.FieldByname('Nombre') then  // Columna de DBGrid donde pintar en este caso es "Nombre".
  4.     begin
  5.       bitmap := TBitmap.Create;
  6.       if  Tabla.FieldByname('Nombre').AsString = 'juan' then
  7.         imgIndex := 0
  8.       else
  9.         imgIndex := 1;
  10.  
  11.       bitmap := TBitmap.Create;
  12.       try
  13.            ImageList1.GetBitmap(imgIndex,bitmap);
  14.  
  15.            bmpWidth := (Rect.Bottom - Rect.Top);
  16.            fixRect.Right := Rect.left + bmpWidth;
  17.            fixRect.Left := fixRect.Left + bmpWidth;
  18.            DBGrid1.Canvas.Draw(fixRect.Left,fixRect.Top+2, bitmap);
  19.       finally
  20.            bitmap.Free;
  21.       end;
  22.  
  23.     end;
  24.     DBGrid1.DefaultDrawColumnCell(fixRect,DataCol,Column,State);

Archivos adjuntos


  • 0

#10 escafandra

escafandra

    Advanced Member

  • Administrador
  • 4.107 mensajes
  • LocationMadrid - España

Escrito 16 mayo 2015 - 08:55

En primer lugar, recordarte las etiquetas de código para que tu mensaje se vea mejor, edito tu mensaje para que lo veas.
 
En segundo lugar, no pusiste todo el código, con lo que debe haber cosas que no muestras.
 
En tercer lugar, usar mal fixRect, lo ajustas para el dibujo desplazándolo a la derecha, cuando eso lo debes hacer para el texto. No modifiques fixRect.Right pues se sale del Rect de la celda.
 
Prueba de esta manera:
 

delphi
  1. procedure TForm1.DBGrid1DrawDataCell(Sender: TObject; const Rect: TRect;
  2. Field: TField; State: TGridDrawState);
  3. var
  4. fixRect: TRect;
  5. bitmap: TBitmap;
  6. imgIndex: Integer;
  7. begin
  8. fixRect:= Rect;
  9. if column.Field = Tabla.FieldByname('Edad') then // compruebo si es la columna=edad para pintar.
  10. begin
  11. if Tabla.FieldByname('Nombre').AsString = 'juan' then
  12. imgIndex:= 0
  13. else
  14. imgIndex:= 1;
  15. bitmap:= TBitmap.Create;
  16.  
  17. try
  18. ImageList1.GetBitmap(imgIndex,bitmap);
  19. DBGrid1.Canvas.Draw(Rect.Left, Rect.Top+2, bitmap);
  20. finally
  21. bitmap.Free;
  22. end;
  23. fixRect.left:= Rect.left + Bitmap.Width + 2; //hago sitio para el texto desplazando Left a la derecha el ancho del bitmap
  24. end;
  25.  
  26. DBGrid1.DefaultDrawColumnCell(fixRect, DataCol, Column, State);
  27. end;

Saludos.
  • 0

#11 escafandra

escafandra

    Advanced Member

  • Administrador
  • 4.107 mensajes
  • LocationMadrid - España

Escrito 16 mayo 2015 - 09:46

Aprovecho para decirte que si tu aplicación corre en entorno windows, puedes revisar este tema para hacer un Stretch de mayor calidad: Redimensionar una imagen con GDI+ flat API. También puedes estudiar el tema del altializasing,

 

Saludos.


  • 0

#12 dooper

dooper

    Advanced Member

  • Miembros
  • PipPipPip
  • 298 mensajes

Escrito 16 mayo 2015 - 01:11

La etiqueta de codigo creo que ya se a que te refieres (etiquetar el  codigo fuente "<>" verdad?) Perdón, no lo sabía, tal cual copiaba, pegaba. Otra cosa nueva!

 

El codigo fuente que he puesto es el que tengo, más arriba simplemente pongo las filas alternas en colores distintos, nada que ver con el codigo de insercción del icono. Si se necesita lo inserto, pero un experto como tú intuyes el codigo que habré puesto, ya que no quiería insertar mas lineas y agrandar el post.

 

En cuanto al resultado, pues seguimos igual, el icono aparece totalmente a la izquierda de la celda, pero encima del texto (ya que el texto en ningun momento se ha movido hacia la derecha para dejar hueco al icono) y además continuo con fila borrada mientras está activa. Un dilema totalmente en mi caso.

 

Tomo nota de tus consejos sobre el tema de Strech de mayor calidad y tambien de altializasing, se agradece tu apoyo y ayuda como así he reconocido a los demás compañeros de este foro. Miraré de que va, pero es normal que si se me atasca lo más fácil, lo que no lo sea tanto puede ser una odisea, pero como así me aconsejaron el tema de Tframes anotado queda para ir avanzando y aprendiendo.

 

Un saludo


  • 0

#13 escafandra

escafandra

    Advanced Member

  • Administrador
  • 4.107 mensajes
  • LocationMadrid - España

Escrito 16 mayo 2015 - 02:47

En cuanto al resultado, pues seguimos igual, el icono aparece totalmente a la izquierda de la celda, pero encima del texto (ya que el texto en ningun momento se ha movido hacia la derecha para dejar hueco al icono) y además continuo con fila borrada mientras está activa. Un dilema totalmente en mi caso.


¿Has usado el código tal cual te lo puse?
Trata de sustituir la línea DefaultDrawColumnCell por:


delphi
  1. DBGrid1.Canvas.TextOut(Rect.Left + Bitmap.Width + 2, Rect.Bottom, 'TEXTO');

A ver que te sale.

 

 

Saludos.


  • 0

#14 dooper

dooper

    Advanced Member

  • Miembros
  • PipPipPip
  • 298 mensajes

Escrito 16 mayo 2015 - 03:34

Pues me salta un error del copón:


php
  1. Error: El proyecto zeos ha lanzado una excepción de la clase 'External: SIGSEGV'.  en dirección FFFF

Ufff, pues no se, si este error es titularidad mia, o esto quiere acabar con mi paciencia, pero no queda otra que no poner ningun icono en la primera columna, pero aun así, porque se borra el contenido de la fila seleccionada apareciendo solamente el icono? veo que el mal de todos los males es el dicho icono en el Grid...

 

Esto mina la moral a un simple iniciado en la materia...

 

Un saludo


  • 0

#15 dooper

dooper

    Advanced Member

  • Miembros
  • PipPipPip
  • 298 mensajes

Escrito 16 mayo 2015 - 04:12

La variable Bitmap.Width me salta por los aire la compilación.

 

En cuanto al problema de la fila seleccionada no aparece en azul aún indicándole rowselect activado. He conseguido ver que es por el codigo de alternar las filas de color que pico encima de insertar el icono.

 

Si elimino el codigo entero, ya si selecciona la fila en azul activa. Pero claro no es mi intención.


php
  1. fixRect := Rect;
  2.      if Odd(tabla.RecNo) then  // método Odd que retorna true si un numero es impar y false si el numero es par.
  3.         DBGrid1.Canvas.Brush.Color:=clcream //$00E1FFF9
  4.     else
  5.              DBGrid1.Canvas.Brush.Color := clwhite; //$00FFEBDF;
  6.  
  7.         DBGrid1.Canvas.Font.color:=clblack;
  8.         DBGrid1.Canvas.FillRect(Rect);
  9.         DBGrid1.DefaultDrawColumnCell(Rect, DataCol, Column, State);


  • 0

#16 escafandra

escafandra

    Advanced Member

  • Administrador
  • 4.107 mensajes
  • LocationMadrid - España

Escrito 16 mayo 2015 - 05:05

La variable Bitmap.Width me salta por los aire la compilación.


Tienes toda la razón, lo escribí al vuelo y no me fijé en que bitmap estaba destruido. Prueba así (al vuelo también):

delphi
  1. procedure TForm1.DBGrid1DrawDataCell(Sender: TObject; const Rect: TRect;
  2. Field: TField; State: TGridDrawState);
  3. var
  4. fixRect: TRect;
  5. bitmap: TBitmap;
  6. imgIndex, bmpwidth: Integer;
  7. begin
  8. fixRect:= Rect;
  9. if column.Field = Tabla.FieldByname('Edad') then // compruebo si es la columna=edad para pintar.
  10. begin
  11. if Tabla.FieldByname('Nombre').AsString = 'juan' then
  12. imgIndex:= 0
  13. else
  14. imgIndex:= 1;
  15. bitmap:= TBitmap.Create;
  16.  
  17. try
  18. ImageList1.GetBitmap(imgIndex,bitmap);
  19. DBGrid1.Canvas.Draw(Rect.Left, Rect.Top+2, bitmap);
  20. finally
  21. bmpwidth:= Bitmap.Width;
  22. bitmap.Free;
  23. end;
  24. fixRect.left:= Rect.left + bmpwidth + 2; //hago sitio para el texto desplazando Left a la derecha el ancho del bitmap
  25. end;
  26.  
  27. DBGrid1.DefaultDrawColumnCell(fixRect, DataCol, Column, State);
  28. end;


También puedes cambiar la línea DefaultDrawColumnCell por: 

delphi
  1. DBGrid1.Canvas.TextOut(Rect.Left + bmpwidth + 2, Rect.top, 'TEXTO');


La palabra TEXTO debe salir en todas las celdas dejando espacio al bitmap.


Saludos.
  • 0

#17 dooper

dooper

    Advanced Member

  • Miembros
  • PipPipPip
  • 298 mensajes

Escrito 16 mayo 2015 - 05:32

Me duplica el contenido del campo nombre y edad.

 

Aparecen dos veces el lacelda el valor del nombre y lo mismo de la edad.

Pero si se aprecia que ahora queda el icono y luego el texto.

 

En la lina aparece probado con edad, para ver si aparecía duplicado y lo mismo digo. El caso es que he tenido que pasarlo a string la edad porque daba error.


php
  1. DBGrid1.Canvas.TextOut(Rect.Left + bmpwidth + 2, Rect.top, InttoStr(Tabla.FieldByname('Edad').AsInteger));


  • 0

#18 escafandra

escafandra

    Advanced Member

  • Administrador
  • 4.107 mensajes
  • LocationMadrid - España

Escrito 17 mayo 2015 - 07:20

Hice un ejemplo en Lazarus y vi el problema, Lazarus pinta si o si, a pesar de reescrivir el evento DrawColumnCell.
Si lo borramos previamente, desaparece el problema:
 

delphi
  1. procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;
  2.   DataCol: Integer; Column: TColumn; State: TGridDrawState);
  3. var
  4.   fixRect: TRect;
  5.   bitmap: TBitmap;
  6.   imgIndex, bmpwidth: Integer;
  7. begin
  8.   DBGrid1.Canvas.Rectangle(Rect);  //Borramos lo que pinta Lazarus
  9.   fixRect:= Rect;
  10.   if column.Field = Tabla.FieldByname('Edad') then  // compruebo si es la columna=edad para pintar.
  11.   begin
  12.     if Tabla.FieldByname('Nombre').AsString = 'Juan' then
  13.       imgIndex:= 0
  14.     else
  15.       imgIndex:= 1;
  16.     bitmap:= TBitmap.Create;
  17.  
  18.     try
  19.       ImageList1.GetBitmap(imgIndex,bitmap);
  20.       DBGrid1.Canvas.Draw(Rect.Left, Rect.Top+2, bitmap);
  21.     finally
  22.       bmpwidth:= Bitmap.Width;
  23.       bitmap.Free;
  24.     end;
  25.     fixRect.left:= Rect.left + bmpwidth + 2;  //hago sitio para el texto desplazando Left a la derecha el ancho del bitmap
  26.   end;
  27.  
  28.   DBGrid1.DefaultDrawColumnCell(fixRect, DataCol, Column, State);
  29. end;


La imagen es un ejemplo pintando el icono en todos los campos:
 
post-12294-0-63310600-1431869049.png
 
 
 
Saludos.

Archivos adjuntos


  • 1

#19 dooper

dooper

    Advanced Member

  • Miembros
  • PipPipPip
  • 298 mensajes

Escrito 17 mayo 2015 - 10:41

Eres un crack amigo! Voy a probarlo en cuanto pueda, porque se me bloquea el equipo cada 10 minutos y no me deja trabajar en paz.

 

Efectivamente me pintaba dos veces como indicas, no pensaba que fuera lazarus sino un problema más bien de programación.

 

En cuanto me deje trabajar el equipo si lo  consigo te pongo a probarlo en mi código, pero me temo que en breve volveré a bloquearme.

 

En cuanto a las filas alternas de distintos colores, ese era el problema de que gsrowwselect no me pinte la fila entera en azul activo,como en tu ejemplo. Veré si puede quitarlo del procedimiento y añadirlo en otro lugar, porque si lo hago quitar si se soluciona el problema.

 

Gracias escafamdra por tu aporte, a enecumene le ocurrió igual y creo que si aún le persiste el problema, podrá con tu ayuda solucionarlo igualmente.

 

Cualquier duda la pondré si la hay...

 

Un saludo


  • 0

#20 escafandra

escafandra

    Advanced Member

  • Administrador
  • 4.107 mensajes
  • LocationMadrid - España

Escrito 17 mayo 2015 - 04:17

En cuanto a las filas alternas de distintos colores, ese era el problema de que gsrowwselect no me pinte la fila entera en azul activo,como en tu ejemplo. Veré si puede quitarlo del procedimiento y añadirlo en otro lugar, porque si lo hago quitar si se soluciona el problema.


Esta es la solución:
 


delphi
  1. procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;
  2. DataCol: Integer; Column: TColumn; State: TGridDrawState);
  3. var
  4. fixRect: TRect;
  5. bitmap: TBitmap;
  6. imgIndex, bmpwidth: Integer;
  7. begin
  8. fixRect:= Rect;
  9. if not(gdSelected in State) then
  10. if Odd(tabla.RecNo) then
  11. DBGrid1.Canvas.Brush.Color:=clcream //$00E1FFF9
  12. else
  13. DBGrid1.Canvas.Brush.Color := clwhite; //$00FFEBDF;
  14.  
  15. DBGrid1.Canvas.Rectangle(Rect);
  16. if column.Field = Tabla.FieldByname('Edad') then // compruebo si es la columna=edad para pintar.
  17. begin
  18. if Tabla.FieldByname('Nombre').AsString = 'Juan' then
  19. imgIndex:= 0
  20. else
  21. imgIndex:= 1;
  22. bitmap:= TBitmap.Create;
  23.  
  24. try
  25. ImageList1.GetBitmap(imgIndex,bitmap);
  26. DBGrid1.Canvas.Draw(Rect.Left, Rect.Top+2, bitmap);
  27. finally
  28. bmpwidth:= Bitmap.Width;
  29. bitmap.Free;
  30. end;
  31. fixRect.left:= Rect.left + bmpwidth + 2; //hago sitio para el texto desplazando Left a la derecha el ancho del bitmap
  32. end;
  33.  
  34. DBGrid1.DefaultDrawColumnCell(fixRect, DataCol, Column, State);
  35. end;

 
 
 
Saludos.


  • 1




IP.Board spam blocked by CleanTalk.