Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > OOP
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 14-07-2005
Ictiandro Ictiandro is offline
Miembro
 
Registrado: jul 2005
Posts: 13
Poder: 0
Ictiandro Va por buen camino
Pintar de un color un THeaderSection o la cabecera de un TListColumn

Hola chicos.
Necesito ayuda, tengo que pintar de un color la cabecera de un TListColumn o en todo caso una sección (es decir THeaderSection) de un THeaderControl. He agotado todos los medios posibles y nose como realizar dicha tarea, cualquier ayuda o guía queda muy agradecida.
Gracias
Responder Con Cita
  #2  
Antiguo 15-07-2005
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
El problema es que el control ListView de Delphi no expone los eventos necesarios para pintar los encabezados.

El HeaderControl sí expone el evento OnCustomDraw para tal efecto pero tratar de sustituir el encabezado de un ListView por uno propio puede tornarse muy complicado para sincronizarlo con las columnas.

La manera en que he visto que logran esto es haciendo uso del siguiente hecho: cuando Windows debe pintar el header, manda un mensaje WM_NOTIFY a la ventana padre- en este caso el ListView -con información relacionada a la etapa de dibujado.

Para captar este mensaje, lo ideal sería crear una componente derivada de TListView; pero para fines prácticos podemos usar el viejo truco de la "componente usurpadora":


Código Delphi [-]
type
  TListView = class(ComCtrls.TListView)
  private
    procedure WMNotify(var Msg: TWMNotify); message WM_NOTIFY;
  end;

  TForm1 = class(TForm)
    ListView1: TListView;
     ...
  end;

Esto es, se declara en la misma unidad que el formulario que contiene al ListView y antes de la declaración de éste, una clase del mismo nombre de la componente que nos interesa que descienda de ella. Esta nueva clase "usurpa" la original haciendo que la componente insertada en el formulario adquiera la nueva funcionalidad.

Para la implementación de WMNotify debemos incluir la unidad CommCtrl (no confundir con ComCtrls) para la definición de las estructuras de datos y constantes necesarias.

La implementación es sencilla:

Código Delphi [-]
{
  El mensaje WM_NOTIFY se usa para muchas cosas así que primero que
  nada hay que determinar que el mensaje es de pintado y que viene
  del header.
}
procedure TListView.WMNotify(var Msg: TWMNotify);
var
  Header: HWnd;
  CustomDraw: PNMCustomDraw;

begin
  // obtener el identificador del header
  Header := Perform(LVM_GETHEADER, 0, 0);

  if (Msg.NMHdr.code = NM_CUSTOMDRAW) and (Msg.NMHdr.hwndFrom = Header) then
  begin
    // estructura de datos con información para el pintado
    CustomDraw := PNMCustomDraw(Msg.NMHdr);

    case CustomDraw.dwDrawStage of
      CDDS_PREPAINT:
        // se le dice a Windows que queremos notificaciones para cada item
        Msg.Result := CDRF_NOTIFYITEMDRAW;

      CDDS_ITEMPREPAINT:
        (*
          dwItemSpec es el índice del item del encabezado (columna)
          que queremos pintar- en este caso 1
        *)
        if CustomDraw.dwItemSpec = 1 then
          // aquí indicamos el color del fondo
          Windows.SetBkColor(CustomDraw.hdc, $00FF8080);
    end;
  end;
end;

// Saludos
Responder Con Cita
  #3  
Antiguo 15-07-2005
Ictiandro Ictiandro is offline
Miembro
 
Registrado: jul 2005
Posts: 13
Poder: 0
Ictiandro Va por buen camino
Muchas gracias Maestro Roman, realmente necesita ayuda con respecto a este problema, me has ahorrado muchas complicaciones y también tiempo.
Responder Con Cita
  #4  
Antiguo 15-07-2005
Ictiandro Ictiandro is offline
Miembro
 
Registrado: jul 2005
Posts: 13
Poder: 0
Ictiandro Va por buen camino
Corrección:
Muchas gracias Maestro Roman, realmente necesitaba ayuda con respecto a este problema, me has ahorrado muchas complicaciones y también tiempo.
Responder Con Cita
  #5  
Antiguo 21-07-2008
jusnjosesch jusnjosesch is offline
Miembro
 
Registrado: mar 2008
Posts: 17
Poder: 0
jusnjosesch Va por buen camino
Red face Algo extraño al pintar las cabezas

Hola:
Ante todo, muchas gracias, encontré este hilo y me solucionó un problema, y me quedó uno menor:
Cuando los títulos del ListView están pintados, al desplazarlos no arrastra toda la columna, solo se mueve el cabezal, pero los datos quedan donde están. He buscado por todos lados, pero no consigo arreglarlo.
Tiene solución, cual es?
Gracias de antemano.




Cita:
Empezado por roman Ver Mensaje
El problema es que el control ListView de Delphi no expone los eventos necesarios para pintar los encabezados.

El HeaderControl sí expone el evento OnCustomDraw para tal efecto pero tratar de sustituir el encabezado de un ListView por uno propio puede tornarse muy complicado para sincronizarlo con las columnas.

La manera en que he visto que logran esto es haciendo uso del siguiente hecho: cuando Windows debe pintar el header, manda un mensaje WM_NOTIFY a la ventana padre- en este caso el ListView -con información relacionada a la etapa de dibujado.

Para captar este mensaje, lo ideal sería crear una componente derivada de TListView; pero para fines prácticos podemos usar el viejo truco de la "componente usurpadora":



Código Delphi [-]
type
TListView = class(ComCtrls.TListView)
private
procedure WMNotify(var Msg: TWMNotify); message WM_NOTIFY;
end;

TForm1 = class(TForm)
ListView1: TListView;
...
end;





Esto es, se declara en la misma unidad que el formulario que contiene al ListView y antes de la declaración de éste, una clase del mismo nombre de la componente que nos interesa que descienda de ella. Esta nueva clase "usurpa" la original haciendo que la componente insertada en el formulario adquiera la nueva funcionalidad.

Para la implementación de WMNotify debemos incluir la unidad CommCtrl (no confundir con ComCtrls) para la definición de las estructuras de datos y constantes necesarias.

La implementación es sencilla:


Código Delphi [-]
{
El mensaje WM_NOTIFY se usa para muchas cosas así que primero que
nada hay que determinar que el mensaje es de pintado y que viene
del header.
}
procedure TListView.WMNotify(var Msg: TWMNotify);
var
Header: HWnd;
CustomDraw: PNMCustomDraw;

begin
// obtener el identificador del header
Header := Perform(LVM_GETHEADER, 0, 0);

if (Msg.NMHdr.code = NM_CUSTOMDRAW) and (Msg.NMHdr.hwndFrom = Header) then
begin
// estructura de datos con información para el pintado
CustomDraw := PNMCustomDraw(Msg.NMHdr);

case CustomDraw.dwDrawStage of
CDDS_PREPAINT:
// se le dice a Windows que queremos notificaciones para cada item
Msg.Result := CDRF_NOTIFYITEMDRAW;

CDDS_ITEMPREPAINT:
(*
dwItemSpec es el índice del item del encabezado (columna)
que queremos pintar- en este caso 1
*)
if CustomDraw.dwItemSpec = 1 then
// aquí indicamos el color del fondo
Windows.SetBkColor(CustomDraw.hdc, $00FF8080);
end;
end;
end;





// Saludos
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro


La franja horaria es GMT +2. Ahora son las 09:33:29.


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
Copyright 1996-2007 Club Delphi