hakanfa
asked on
TTreeView and different fonts within one node
Hello!
I'm using the TTreeView to mimic the "folder tree" in MS Outlook. Is it possible to set different font colors within one node,
like when You have ex. e few underad mails in one folder the amount is displayed in blue, the other text is bolded black.
I suppose it can be done with OnCustomDrawItem, but cannot figure out how...
Ex. We have three nodes in a TreeView: "Drafts", "Inbox", "Sent Items". I would like the "Inbox" to be drawn as "Inbox" in Bold black and after that "(12)" with
normal font in blue.
Any suggestions?
Hokki
I'm using the TTreeView to mimic the "folder tree" in MS Outlook. Is it possible to set different font colors within one node,
like when You have ex. e few underad mails in one folder the amount is displayed in blue, the other text is bolded black.
I suppose it can be done with OnCustomDrawItem, but cannot figure out how...
Ex. We have three nodes in a TreeView: "Drafts", "Inbox", "Sent Items". I would like the "Inbox" to be drawn as "Inbox" in Bold black and after that "(12)" with
normal font in blue.
Any suggestions?
Hokki
You might also find this functionality within the highly recommended VirtualTreeView from SoftGems
Take a look at
http://www.delphi-gems.com/VirtualTreeview/
Take a look at
http://www.delphi-gems.com/VirtualTreeview/
ASKER
Semen,
I'm sorry to say but I couldn't get Your code working as expected.. A few comments though, the "Inbox" is not always the first node (a small thing but..), Is it necessary to turn "DefaultDraw" off for modifying a portion of text? Can You help me a little more?
Mike,
I checked the VirtualTreeView (the demos) but couldn't find a suitable demo that shows these features.. You don't happen to have a demo using this component showing these features that I mentioned in my first message?
brdgs,
-hokki
I'm sorry to say but I couldn't get Your code working as expected.. A few comments though, the "Inbox" is not always the first node (a small thing but..), Is it necessary to turn "DefaultDraw" off for modifying a portion of text? Can You help me a little more?
Mike,
I checked the VirtualTreeView (the demos) but couldn't find a suitable demo that shows these features.. You don't happen to have a demo using this component showing these features that I mentioned in my first message?
brdgs,
-hokki
VirtualTreeView requires some learning to do before you can use it effectively, but after you learn how to use it, it's defenitively a great tool.
Example of using VirtualTreeView and OnPanitText event
//** Node data
type
PNodeData = ^TNodeData;
TNodeData = record
Text: string;
ItemType: integer;
Status: integer;
AnObject: TSomeObject;
end;
procedure TForm1.VirtualStringTree1P aintText(S ender: TBaseVirtualTree;
const TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex;
TextType: TVSTTextType);
var
data: PNodeData;
begin
data := VirtualStringTree1.GetNode Data(Node) ;
if data = nil then
Exit;
TargetCanvas.Font.Style := [];
if data^.Status = 1 then
TargetCanvas.Font.Style := [fsBold]
if data^.ItemType = 1 then
TargetCanvas.Font.Style := TargetCanvas.Font.Style + [fsItalic];
if data^.AnObject.SomeFunctio n then
TargetCanvas.Font.Color := clBlue;
end;
If you use instead TreeView, then you can do all in OnCustomDrawItem event.
Just keep DefaultDraw true and set needed font properties for canvas.
procedure TForm1.TreeView1CustomDraw Item(Sende r: TCustomTreeView;
Node: TTreeNode; State: TCustomDrawState; var DefaultDraw: Boolean);
begin
DefaultDraw := true;
if Node.Text = 'Some text' then
Sender.Canvas.Font.Style := [fsBold];
if Node.Data = @SomeVar then
Sender.Canvas.Font.Color := clBlue;
end;
Example of using VirtualTreeView and OnPanitText event
//** Node data
type
PNodeData = ^TNodeData;
TNodeData = record
Text: string;
ItemType: integer;
Status: integer;
AnObject: TSomeObject;
end;
procedure TForm1.VirtualStringTree1P
const TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex;
TextType: TVSTTextType);
var
data: PNodeData;
begin
data := VirtualStringTree1.GetNode
if data = nil then
Exit;
TargetCanvas.Font.Style := [];
if data^.Status = 1 then
TargetCanvas.Font.Style := [fsBold]
if data^.ItemType = 1 then
TargetCanvas.Font.Style := TargetCanvas.Font.Style + [fsItalic];
if data^.AnObject.SomeFunctio
TargetCanvas.Font.Color := clBlue;
end;
If you use instead TreeView, then you can do all in OnCustomDrawItem event.
Just keep DefaultDraw true and set needed font properties for canvas.
procedure TForm1.TreeView1CustomDraw
Node: TTreeNode; State: TCustomDrawState; var DefaultDraw: Boolean);
begin
DefaultDraw := true;
if Node.Text = 'Some text' then
Sender.Canvas.Font.Style := [fsBold];
if Node.Data = @SomeVar then
Sender.Canvas.Font.Color := clBlue;
end;
ASKER
A comment..
I've tried to do it the simple way..
procedure TForm1.TreeView1CustomDraw Item(Sende r: TCustomTreeView;
Node: TTreeNode; State: TCustomDrawState; var DefaultDraw: Boolean);
var
r:TRect;
begin
if Node.Text = 'Inbox' then
begin
r:=Node.DisplayRect(True);
Statusbar1.SimpleText:='Le ft:'+ IntToStr(r.Left)+','+ 'Right:'+ IntToStr(r.Right)+','+'Top :'+ IntToStr(r.Top)+','+'Botto m:'+ IntToStr(r.Bottom);
Sender.Canvas.Font.Style := [];
Sender.Canvas.Font.Name:=' Tahoma';
Sender.Canvas.Font.Size:=8 ;
Sender.Canvas.TextOut(r.Ri ght,r.Top, '(12)');
end;
end;
This goes well almost..
1. The "Inbox" text is a a different font..? Why?
2. How do i gewt the text for "(12)" painted blue?
3. When I selected the node, the "(12)" text is also selected, I would like to avoid this (should be static)
Any Ideas?
-hokki
I've tried to do it the simple way..
procedure TForm1.TreeView1CustomDraw
Node: TTreeNode; State: TCustomDrawState; var DefaultDraw: Boolean);
var
r:TRect;
begin
if Node.Text = 'Inbox' then
begin
r:=Node.DisplayRect(True);
Statusbar1.SimpleText:='Le
Sender.Canvas.Font.Style := [];
Sender.Canvas.Font.Name:='
Sender.Canvas.Font.Size:=8
Sender.Canvas.TextOut(r.Ri
end;
end;
This goes well almost..
1. The "Inbox" text is a a different font..? Why?
2. How do i gewt the text for "(12)" painted blue?
3. When I selected the node, the "(12)" text is also selected, I would like to avoid this (should be static)
Any Ideas?
-hokki
ASKER
jpedef,
Thank You for showing the VirtualTreeView, but.. the change is so remarkable compared to an ordinary TreeView, that I would have to re-work the whole project.. what a shame. Anyhow, the other code (ordinary treeview) Do You think that You can support me with a little more detailed code? Like how to handle the Node.Data and as i mentioned before paint som "static" text in a different color?
brdgs,
Hokki
Thank You for showing the VirtualTreeView, but.. the change is so remarkable compared to an ordinary TreeView, that I would have to re-work the whole project.. what a shame. Anyhow, the other code (ordinary treeview) Do You think that You can support me with a little more detailed code? Like how to handle the Node.Data and as i mentioned before paint som "static" text in a different color?
brdgs,
Hokki
ASKER
Hmm. doing some progress here..
I now get it painted "static" as I want, but still some problems.
1. how to handle the strange font for the other text
2. when you select the node, it paint a "shadow" of the text amended "(12)".
Code as follows: (what am I doing wrong??)
procedure TForm1.TreeView1CustomDraw Item(Sende r: TCustomTreeView;
Node: TTreeNode; State: TCustomDrawState; var DefaultDraw: Boolean);
var
bmp:TBitMap;
s:string;
pt:TPoint;
r:TRect;
begin
if Node.Text = 'Inbox' then
begin
DefaultDraw:=True;
s:='(12)' ;
r:=Node.DisplayRect(false) ;
BMP:=TBitmap.Create;
BMP.Width:=Canvas.TextWidt h(s);
BMP.Height:=Canvas.TextHei ght(S) ;
bmp.Canvas.Font.Color:=clB lue;
bmp.Canvas.Brush.Style:=bs Clear;
bmp.Canvas.TextOut(0,0,s);
Pt.x:=r.Right+10;
Pt.y:=r.Top;
if INteger(BitBlt(sender.Canv as.Handle, Pt.x,Pt.y, BMP.Width, BMP.Height ,BMP.Canva s.Handle,0 ,0,SRCCOPY )) = 0 then
Statusbar1.SimpleText:='Er ror painting Node...';
bmp.Free;
end;
end;
I now get it painted "static" as I want, but still some problems.
1. how to handle the strange font for the other text
2. when you select the node, it paint a "shadow" of the text amended "(12)".
Code as follows: (what am I doing wrong??)
procedure TForm1.TreeView1CustomDraw
Node: TTreeNode; State: TCustomDrawState; var DefaultDraw: Boolean);
var
bmp:TBitMap;
s:string;
pt:TPoint;
r:TRect;
begin
if Node.Text = 'Inbox' then
begin
DefaultDraw:=True;
s:='(12)' ;
r:=Node.DisplayRect(false)
BMP:=TBitmap.Create;
BMP.Width:=Canvas.TextWidt
BMP.Height:=Canvas.TextHei
bmp.Canvas.Font.Color:=clB
bmp.Canvas.Brush.Style:=bs
bmp.Canvas.TextOut(0,0,s);
Pt.x:=r.Right+10;
Pt.y:=r.Top;
if INteger(BitBlt(sender.Canv
Statusbar1.SimpleText:='Er
bmp.Free;
end;
end;
ASKER
Hrmm..increasing to 500....
ASKER
OK.. got it working. Little tricky with the handle.
Here's the code if someone needs it..
procedure TForm1.TreeView1CustomDraw Item(Sende r: TCustomTreeView;
Node: TTreeNode; State: TCustomDrawState; var DefaultDraw: Boolean);
var
bmp: TBitMap;
s: string;
pt: TPoint;
r: TRect;
DC: HWND;
begin
if Node.Text = 'Inbox' then
begin
s := '(12)';
Sender.Canvas.Font.Style := [fsBold];
r := Node.DisplayRect(true);
bmp := TBitmap.Create;
bmp.Width := Canvas.TextWidth(s);
bmp.Height := Canvas.TextHeight(S);
bmp.Canvas.Font.Color := clBlue;
bmp.Canvas.Brush.Style := bsClear;
bmp.Canvas.TextOut(0, 0, s);
Pt.x := r.Left + sender.Canvas.TextWidth(No de.Text)+6 ;
Pt.y := r.Top + 2;
DC := GetDC(sender.Handle);
BitBlt(DC, pt.x, pt.y, BMP.Width, BMP.Height, BMP.Canvas.Handle, 0, 0, SRCCOPY);
bmp.Free;
ReleaseDC(sender.Handle, DC);
DefaultDraw := True;
end;
end;
-hokki
Here's the code if someone needs it..
procedure TForm1.TreeView1CustomDraw
Node: TTreeNode; State: TCustomDrawState; var DefaultDraw: Boolean);
var
bmp: TBitMap;
s: string;
pt: TPoint;
r: TRect;
DC: HWND;
begin
if Node.Text = 'Inbox' then
begin
s := '(12)';
Sender.Canvas.Font.Style := [fsBold];
r := Node.DisplayRect(true);
bmp := TBitmap.Create;
bmp.Width := Canvas.TextWidth(s);
bmp.Height := Canvas.TextHeight(S);
bmp.Canvas.Font.Color := clBlue;
bmp.Canvas.Brush.Style := bsClear;
bmp.Canvas.TextOut(0, 0, s);
Pt.x := r.Left + sender.Canvas.TextWidth(No
Pt.y := r.Top + 2;
DC := GetDC(sender.Handle);
BitBlt(DC, pt.x, pt.y, BMP.Width, BMP.Height, BMP.Canvas.Handle, 0, 0, SRCCOPY);
bmp.Free;
ReleaseDC(sender.Handle, DC);
DefaultDraw := True;
end;
end;
-hokki
Having read this thread from an outsider's perspective, I think the question has been answered and points should be awarded to sas13 and jpedef.
ASKER
Aikimark,
Would You please try the sas13 solution.! It doesent work (I did not get it workin anyway), how can I accept such an answer..??
-hokki
Would You please try the sas13 solution.! It doesent work (I did not get it workin anyway), how can I accept such an answer..??
-hokki
hokki,
I wrote my comments based on the information you told us "OK.. got it working".
<<Would You please try the sas13 solution>>
It wouldn't do any good, since I don't have the rest of your application and can't evaluate what you need for your user interface.
<<how can I accept such an answer?>>
1. keep working on the solution and ask questions. This question is only 6 days old.
2. if the question rolls off the first page and it is urgent, you can post a 20 point question with a link to this one.
3. if you are close but have other questions, then close this one and open another question.
I wrote my comments based on the information you told us "OK.. got it working".
<<Would You please try the sas13 solution>>
It wouldn't do any good, since I don't have the rest of your application and can't evaluate what you need for your user interface.
<<how can I accept such an answer?>>
1. keep working on the solution and ask questions. This question is only 6 days old.
2. if the question rolls off the first page and it is urgent, you can post a 20 point question with a link to this one.
3. if you are close but have other questions, then close this one and open another question.
ASKER
Aahh, now i understand. With "OK..got it working" I ment I figured out by my self..
As You can see from "my solution" there is nothing in common with the sas12 proposal.. You see?
-hokki
As You can see from "my solution" there is nothing in common with the sas12 proposal.. You see?
-hokki
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Node: TTreeNode; State: TCustomDrawState; var DefaultDraw: Boolean);
var
_bmp: TBitmap;
_off: integer;
_rect: TRect;
begin
if Node.AbsoluteIndex = 0 then begin
DefaultDraw := false;
Sender.Canvas.Brush.Style := bsSolid;
Sender.Canvas.Brush.Color := TTreeView(Sender).Color;
Sender.Canvas.FillRect(Nod
_bmp := TBitmap.Create;
if Assigned(TTreeView(Sender)
Sender.Canvas.Draw(0, 1, _bmp);
_bmp.Free;
if cdsSelected in State then
Sender.Canvas.Brush.Color := clHighlight;
_rect := Node.DisplayRect(true);
_rect.Right := Node.DisplayRect(false).Ri
Sender.Canvas.TextRect(_re
Inc(_rect.Left, Sender.Canvas.TextWidth('I
Sender.Canvas.Font.Style := [fsBold];
Sender.Canvas.TextRect(_re
Inc(_rect.Left, Sender.Canvas.TextWidth('(
Sender.Canvas.Brush.Color := clBlue;
Sender.Canvas.Font.Style := [];
Sender.Canvas.TextRect(_re
Inc(_rect.Left, Sender.Canvas.TextWidth('o
_off := _rect.Left;
_rect := Node.DisplayRect(true);
_rect.Right := _off;
if cdsFocused in State then
Sender.Canvas.DrawFocusRec
end
end;