Delphi TListview OwnerDraw SubItems-cambie la fuente predeterminada(de alguna manera es negrita después de dibujar en el lienzo)
ownerdrawn (2)
Si utiliza ownerdraw con un TListView, los subelementos son todos estilo de fuente BOLD por defecto de alguna manera, incluso si listview font.style está establecido en [], para todos los SubItems siguiendo un dibujado personalizado.
Una solución alternativa que encontré es forzar el conjunto de estilos en el evento CustomDrawSubItem:
ListView2.Canvas.Font.Style := [fsItalic];
ListView2.Canvas.Font.Style := [];
(Una llamada simple con [] no funcionará a menos que el estilo predeterminado esté configurado en algo distinto de [], porque la llamada SetStyle no cree que el estilo haya cambiado)
Sin embargo, esta es una solución desagradable que implica un tiempo de procesamiento adicional. ¿Hay una mejor solución?
Proyecto de demostración: http://www.mediafire.com/?v8bsdpvpfqy47vn
Estoy de acuerdo con el comentario de jachguate con que parece haber un problema con el control de VCL; un posible problema de diseño con TCustomListView.CNNotify
. Pero no es fácil seguir la lógica allí.
Una solución es forzar un cambio en el lienzo del control cuando DefaultDraw es verdadero, de modo que el VCL crea y selecciona la fuente del control nuevamente en el DC enviado antes de que regrese la notificación de dibujo personalizado. Ejemplo:
procedure TForm1.LVCustomDrawSubItem(Sender: TCustomListView; Item: TListItem;
SubItem: Integer; State: TCustomDrawState; var DefaultDraw: Boolean);
Var R: TRect;
bmp: TBitmap;
x: Integer;
begin
DefaultDraw := True;
if SubItem = 1 then begin
DefaultDraw := False;
...
...
Sender.Canvas.Draw(R.Left - 2, R.Top, Bmp);
Bmp.Free;
end;
end;
if DefaultDraw then
Sender.Canvas.Brush.Color := ColorToRGB(clWindow); // <--
end;
La forma en que preferiría es evitar usar el lienzo del control, si es posible. Puede usar un DC temporal para su caso, esto también evita el problema de fondo negro mencionado en los comentarios a la pregunta.
uses
commctrl;
...
procedure TForm1.LVCustomDrawSubItem(Sender: TCustomListView; Item: TListItem;
SubItem: Integer; State: TCustomDrawState; var DefaultDraw: Boolean);
Var R: TRect;
bmp: TBitmap;
x: Integer;
DC: HDC;
begin
DefaultDraw := True;
if SubItem = 1 then begin
DefaultDraw := False;
...
...
DC := GetDC(Sender.Handle);
ImageList_Draw(TypeImages.Handle, 0, DC, R.Left - 2, R.Top, ILD_NORMAL);
ReleaseDC(Sender.Handle, DC);
Bmp.Free;
end;
end;
end;
No he encontrado la situación exacta que describes, pero he encontrado un problema similar. Cuando uso un TListView
dibujado por el TListView
con un evento OnAdvancedCustomDrawSubItem
asignado para cambiar el Canvas.Font
en Canvas.Font
a un Canvas.Font
, me parece que después de haber cambiado el Sender.Canvas.Font
para un subelemento, los Sender.Canvas.Font
subsiguientes se dibujan con el incorrecto configuración incluso si cambio el Sender.Canvas.Font
para ellos. Mi solución alternativa es llamar manualmente al controlador de eventos Sender.Canvas.Font.OnChange
al final de mi controlador de eventos OnAdvancedCustomDrawSubItem
. Eso indica a TListView
que informe CDRF_NEWFONT
a Windows, luego todo se dibuja correctamente. Es como si el evento Sender.Canvas.Font.OnChange
no Sender.Canvas.Font.OnChange
conectado correctamente mientras TListView
está siendo dibujado por el propietario, por lo que no detecta cambios de fuente y, por lo tanto, no informa correctamente a Windows.