delphi ownerdrawn tlistview

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.