steve-west
asked on
Customdraw TreeView - cannot change font colour
Overriding the CustomDrawItem event and setting default draw to false - thereby performing all the drawing of the tree nodes myself.
If find that I'm allowed one change of font colour. Any changes after this are being ignored.
For example
var
DisplayText : string;
NodeRect : TRect;
With TTreeView(Sender).Canvas do
begin
DefaultDraw := false;
NodeRect := Node.DisplayRect(False);
FillRect(NodeRect);
Font.Color := clBlue;
DisplayText := Node.Text;
DrawText(Handle, DisplayText[1], Length(DisplayText), NodeRect, dt_SingleLine or dt_vcenter);
NodeRect.Left := Noderect.Left + 100;
Font.Color := clGreen;
DrawText(Handle, DisplayText[1], Length(DisplayText), NodeRect, dt_SingleLine or dt_vcenter);
end;
This will display both occurrences of the text in the colour blue.
Any ideas anyone?
Thanks
Steve
If find that I'm allowed one change of font colour. Any changes after this are being ignored.
For example
var
DisplayText : string;
NodeRect : TRect;
With TTreeView(Sender).Canvas do
begin
DefaultDraw := false;
NodeRect := Node.DisplayRect(False);
FillRect(NodeRect);
Font.Color := clBlue;
DisplayText := Node.Text;
DrawText(Handle, DisplayText[1], Length(DisplayText), NodeRect, dt_SingleLine or dt_vcenter);
NodeRect.Left := Noderect.Left + 100;
Font.Color := clGreen;
DrawText(Handle, DisplayText[1], Length(DisplayText), NodeRect, dt_SingleLine or dt_vcenter);
end;
This will display both occurrences of the text in the colour blue.
Any ideas anyone?
Thanks
Steve
Sorry... OnCustomDrawItem event... not at OnCustomDraw as i formerly said.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Try Like this
For example
var
DisplayText : string;
NodeRect : TRect;
With TTreeView(Sender).Canvas do
begin
DefaultDraw := false;
NodeRect := Node.DisplayRect(False);
FillRect(NodeRect);
Font.Color := clBlue;
DisplayText := Node.Text;
DrawText(Handle, DisplayText[1], Length(DisplayText), NodeRect, dt_SingleLine or dt_vcenter);
NodeRect.Left := Noderect.Left + 100;
Font.Color := clGreen;
refresh;
DrawText(Handle, DisplayText[1], Length(DisplayText), NodeRect, dt_SingleLine or dt_vcenter);
end;
For example
var
DisplayText : string;
NodeRect : TRect;
With TTreeView(Sender).Canvas do
begin
DefaultDraw := false;
NodeRect := Node.DisplayRect(False);
FillRect(NodeRect);
Font.Color := clBlue;
DisplayText := Node.Text;
DrawText(Handle, DisplayText[1], Length(DisplayText), NodeRect, dt_SingleLine or dt_vcenter);
NodeRect.Left := Noderect.Left + 100;
Font.Color := clGreen;
refresh;
DrawText(Handle, DisplayText[1], Length(DisplayText), NodeRect, dt_SingleLine or dt_vcenter);
end;
You can also switch to using WinAPI to change font color in both places.
Instead of
Font.Color := clBlue;
use
SetTextColor(Handle, clBlue); // Handle - TreeView's Canvas.Handle
Instead of
Font.Color := clBlue;
use
SetTextColor(Handle, clBlue); // Handle - TreeView's Canvas.Handle
ASKER
Hi dinlud
Thanks for this but wouldn't calling the refresh method during a paint process result in an infinite loop?
Anyway
Thanks for all who have contributed to this.
sas13 - your answer is the one that works the best - really all component drawing like this should be performed off screen.
Thanks to everyone
Steve
Thanks for this but wouldn't calling the refresh method during a paint process result in an infinite loop?
Anyway
Thanks for all who have contributed to this.
sas13 - your answer is the one that works the best - really all component drawing like this should be performed off screen.
Thanks to everyone
Steve
Hi Steve,
>>>.....wouldn't calling the refresh method during a paint process result in an infinite loop?
This is my reply. What ever your reply please post.(This is just for a fun)
Unit1.dfm
=======
object Form1: TForm1
Left = 3
Top = 197
Width = 773
Height = 199
Caption = 'Form1'
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -16
Font.Name = 'MS Sans Serif'
Font.Style = [fsBold]
OldCreateOrder = False
OnPaint = FormPaint
PixelsPerInch = 96
TextHeight = 20
object Button1: TButton
Left = 288
Top = 112
Width = 97
Height = 41
Caption = 'Button1'
TabOrder = 0
OnClick = Button1Click
end
end
Unit1.pas
=======
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
procedure FormPaint(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormPaint(Sender: TObject);
begin
Canvas.TextOut(100,50,'Cli ck On Button.If text not changed, then i will accept your reply.');
end;
procedure TForm1.Button1Click(Sender : TObject);
begin
Canvas.FillRect(Canvas.Cli pRect);
Canvas.Refresh ;
Canvas.TextOut(100,50,'Now did you accept my answer?. i except your reply. This is just for fun');
end;
end.
>>>.....wouldn't calling the refresh method during a paint process result in an infinite loop?
This is my reply. What ever your reply please post.(This is just for a fun)
Unit1.dfm
=======
object Form1: TForm1
Left = 3
Top = 197
Width = 773
Height = 199
Caption = 'Form1'
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -16
Font.Name = 'MS Sans Serif'
Font.Style = [fsBold]
OldCreateOrder = False
OnPaint = FormPaint
PixelsPerInch = 96
TextHeight = 20
object Button1: TButton
Left = 288
Top = 112
Width = 97
Height = 41
Caption = 'Button1'
TabOrder = 0
OnClick = Button1Click
end
end
Unit1.pas
=======
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
procedure FormPaint(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormPaint(Sender: TObject);
begin
Canvas.TextOut(100,50,'Cli
end;
procedure TForm1.Button1Click(Sender
begin
Canvas.FillRect(Canvas.Cli
Canvas.Refresh ;
Canvas.TextOut(100,50,'Now
end;
end.
>> Thanks for this but wouldn't calling the refresh method during a paint process result in an infinite loop?
Answer is in the help of Delphi ;)
TControl.Refresh and TCanvas.Refresh do different things. Why I am talking about TControl? Because TControl is ancestor of TTreeView (TControl -> TWinControl -> TCustomTreeView -> TTreeView).
TControl.Refresh - Repaints the control on the screen.
TCanvas.Refresh - Deselects the Pen, Brush, and Font from the device context.
Answer is in the help of Delphi ;)
TControl.Refresh and TCanvas.Refresh do different things. Why I am talking about TControl? Because TControl is ancestor of TTreeView (TControl -> TWinControl -> TCustomTreeView -> TTreeView).
TControl.Refresh - Repaints the control on the screen.
TCanvas.Refresh - Deselects the Pen, Brush, and Font from the device context.
ASKER
ZhaawZ / dinilud:
Accepted ;)
I thought the refresh call would have called the Refresh of the form, not of the Canvas. I wasn't
aware of the Canvas.Refresh method.
Steve
Accepted ;)
I thought the refresh call would have called the Refresh of the form, not of the Canvas. I wasn't
aware of the Canvas.Refresh method.
Steve
Thank you.
procedure TForm1.tvTareasCustomDrawI
var i: integer;
begin
//this portion of code change color and font properties depending on a state
i := eTareas.IndexOf(Node.Text)
if i <> -1 then
with (Sender as TTreeView) do
with Canvas do
begin
case i of
eWaiting: begin
Brush.Color := clRed;
Font.Color := clWhite;
end;
eStandBy : Brush.Color := clYellow;
eFinished: begin
Brush.Color := clGreen;
Font.Color := clWhite;
end;
end;
//Font.Style := [fsBold];
end;
//this portion paint internal nodes
i := eNotas.IndexOf(Node.Text);
if i <> -1 then
with (Sender as TTreeView) do
with Canvas do
begin
case i of
ePendiente : Brush.Color := clRosa;
eStandBy : Brush.Color := clAmarillo;
eFinalizada: Brush.Color := clVerde;
end;
//Font.Style := [fsBold];
end;
//this paint most important nodes
if Node.Parent = nil then
with (Sender as TTreeView) do
with Canvas do
Font.Color := clNavy;
// else if Node.Parent.Parent = nil then
//this put bold for all text in the treeview
with (Sender as TTreeView) do
with Canvas do
Font.Style := [fsBold];
end;
Hope this help!