Page 1 of 1

Exception when creating many nodes with icons

Posted: Tue May 25, 2010 9:59 am
by 10546756
Hello!

Se code below. When running with Quantity set to 40 or below everything works fine. But when I increase the number of nodes and set Quantity to 50 or higher the program chraches with error "Access denied". The ImageList contains 3 icons 32*32 in size.

Any ideas?

Regards, Mikael


Procedure TForm4.FormShow(Sender: TObject);
Const Quantity = 40;
Var I: Integer;
GroupNode: TTreeNodeShape;
UnitNode: TTreeNodeShape;
ChannelNode: TTreeNodeShape;
Z, Y: Integer;
Begin
For I := 1 To Quantity Do
Begin
GroupNode := Tree.AddRootObject('Group ' + intToStr(I), TNodeData.Create);
GroupNode.ImageListIndex := 0;
For Z := 1 To Quantity Do
Begin
UnitNode := GroupNode.AddChildObject('Unit ' + IntToStr(I) + ' - ' + IntToStr(Z), TNodeData.Create);
UnitNode.ImageListIndex := 1;
For Y := 1 To 4 Do
Begin
ChannelNode := UnitNode.AddChildObject('Channel ' + IntToStr(Y), TNodeData.Create);
ChannelNode.ImageListIndex := 2;
End;
End;
End;
End;

Re: Exception when creating many nodes with icons

Posted: Tue May 25, 2010 2:49 pm
by yeray
Hi Michael,

It sounds like a memory limitation. I see that you are creating an exponential growing number of nodes: Quantity + Quantity*Quantity + Quantity*Quantity*4.
With 40, if I'm not wrong, it's 40+1600+6400=8040 nodes
With 50... 50+2500+10000=12550 nodes
And each node has more than 30 properties to store...

Re: Exception when creating many nodes with icons

Posted: Tue May 25, 2010 5:02 pm
by 10546756
Yes, I realize it's a lot of nodes but still only a couple of thousand! Even if each node uses 1kB it's only 12 Mb! I have 4 Gb in the machine.
In your example you have an "Add 50000 nodes" example!

I think the problem is that the bitmap image is duplicated for each node, but it should really only be a pointer to the TImageList!

Regards, Mikael

Re: Exception when creating many nodes with icons

Posted: Tue May 25, 2010 5:11 pm
by 10546756
Tested the program memory usage.

With Count = 30 it takes 14124 Mb memory
With Count = 31 it takes 14663 Mb memory
With Count = 32 it craches!

Regards, Mikael

Re: Exception when creating many nodes with icons

Posted: Wed May 26, 2010 1:42 pm
by yeray
Hi Mikael,

Right. As you've noticed with the TeeTreeCompare sample application, this limit doesn't seem to be caused for the number of nodes created, but probably for the number of images loaded.
I'm not sure why, but the same limitation can be observed here without using TeeTree:

Code: Select all

uses ExtCtrls, PngImage;

procedure TForm1.Button1Click(Sender: TObject);
const NumImages = 4900; //5000;
var i: Integer;
    img: TImage;
begin
  for i:=0 to NumImages-1 do
  begin
    img:=TImage.Create(Self);
    //img.Picture.LoadFromFile('C:\tmp\32_button_green.png');
    img.Picture.Bitmap.LoadFromFile('C:\tmp\32_button_green.bmp');
    img.Parent:=Self;
  end;
end;
We've seen that the threshold seems to be between 4900 and 5000 Images. With 4900 the application above still works fine for us here, but with 5000 it crashes.

Re: Exception when creating many nodes with icons

Posted: Mon Jul 12, 2010 10:55 am
by 10546756
Hello!

Now some of my customers have reached a point where this gets a problem! Is it something you can fix?
As I mentioned before I think the problem is that the bitmap image is copied into each node instead if just using a ponter to the image. Totally I use just about 10 images byt they are duplicated thousands of times.

regards, Mikael

Re: Exception when creating many nodes with icons

Posted: Tue Jul 13, 2010 11:22 am
by yeray
Hi Mikael,

Here you have a workaround. It consists on not to load the images and use custom drawing to draw the symbol.

Code: Select all

procedure TForm1.FormCreate(Sender: TObject);
Const Quantity = 40;
Var I: Integer;
    GroupNode: TTreeNodeShape;
    UnitNode: TTreeNodeShape;
    ChannelNode: TTreeNodeShape;
    Z, Y: Integer;
Begin
  For I := 1 To Quantity Do
  Begin
    GroupNode := Tree1.AddRoot('Group ' + intToStr(I));
    GroupNode.Tag:=0;
    For Z := 1 To Quantity Do
    Begin
      UnitNode := GroupNode.AddChild('Unit ' + IntToStr(I) + ' - ' + IntToStr(Z));
      UnitNode.Tag:=1;
      For Y := 1 To 4 Do
      Begin
        ChannelNode := UnitNode.AddChild('Channel ' + IntToStr(Y));
        ChannelNode.Tag:=2;
      End;
    End;
  End;
end;

procedure TForm1.Tree1AfterDraw(Sender: TObject);
var i: Integer;
    tmpBitmap: TBitmap;
    R: TRect;
begin
  for i:=0 to Tree1.Shapes.Count-1 do
    if Tree1.Shape[i].Visible=true then
    begin
      tmpBitmap:=TBitmap.Create;
      R:=Tree1.Shape[i].ImageRect;
      ImageList1.GetBitmap(Tree1.Shape[i].Tag,tmpBitmap);
      with Tree1.Canvas do
      begin
        StretchDraw(R,tmpBitmap);
      end;
    end;
end;

Re: Exception when creating many nodes with icons

Posted: Mon Aug 09, 2010 9:25 am
by 10546756
Ok, thanks. It kind of works! But there are still problems.

1: When i use the scrollbar all text and the "tree" is moving but my custom icons are not! Any idea hos to fix this.

2: It also seems like the ImageRect coordinates give the wrong position. I can see part of the standard yellow "folder" icon beneth my custom drawn icon.

3: Instead of using ImageRect, is there another way of getting the coordinates for the entire region including icon and text.

3: Is there a way to make the entire drawing custom, including text? Like the DefaultTrawing propertie in TStringGrid.

Regards, Mikael

Re: Exception when creating many nodes with icons

Posted: Mon Aug 09, 2010 3:15 pm
by 10546756
After some research I found some answers myself.

1: When i use the scrollbar all text and the "tree" is moving but my custom icons are not! Any idea hos to fix this.
> This is still a big problem MAKING THE SOLUTION UNUSABLE!

2: It also seems like the ImageRect coordinates give the wrong position. I can see part of the standard yellow "folder" icon beneth my custom drawn icon.
> No its the correct coordinates, the problem was that the horisontal scollbar had moved. Same problem as above!

3: Instead of using ImageRect, is there another way of getting the coordinates for the entire region including icon and text.
> Found it, AdjustedRectangle

3: Is there a way to make the entire drawing custom, including text? Like the DefaultDrawing propertie in TStringGrid.
> Still an issue

Regards, Mikael

Re: Exception when creating many nodes with icons

Posted: Mon Aug 09, 2010 9:04 pm
by 10546756
Almost solved everything by myself now :-)

Found out that I have to adjust the position with the Scrollbar offsets as below:

DrawArea := Tree.Shape.AdjustedRectangle;
DrawArea.Top := DrawArea.Top - UnitTree.VertScrollBar.Position;
DrawArea.Bottom := DrawArea.Bottom - UnitTree.VertScrollBar.Position;
DrawArea.Left := DrawArea.Left - UnitTree.HorzScrollBar.Position;
DrawArea.Right := DrawArea.Right - UnitTree.VertScrollBar.Position;
UnitTree.Canvas.FillRect(DrawArea); <- This is the area where I now can custom draw icons and text.
UnitTree.Canvas.DoAllMyDrawing(DrawArea);

I now only have one more problem and it's how to disable the Horisontal scrollbar.
When drawing text that is wider than the Tree.Width the entire drawarea is scrolled horisontally!
Is it possible to disable this feature?

regards, Mikael

Re: Exception when creating many nodes with icons

Posted: Wed Aug 11, 2010 8:15 am
by yeray
Hi Mikael,

I think the following disables the HorizontalScrollBar.

Code: Select all

Tree1.HorzScrollBar.Automatic:=false;
If you still have problems with it, please try to arrange a simple example project we can run as-is to reproduce the situation here.

Re: Exception when creating many nodes with icons

Posted: Wed Aug 11, 2010 9:55 am
by 10546756
Ok, I made a sample projekt below.

Problem 1:
If you run it and expand the root and then click a node you can see that it moves horizontally without showing any horizontal scrollbar!
I want to disable this horizontal scrolling, I want it to be always left justified.

Problem 2:
If you now uncomment the line with "Node.Height := 26;" and run the project you can see that all nodes get the text position wrong!
This is not a big issue as I'm going to custom draw all text but I dont understand why!?

Code: Select all


object Form1: TForm1
  Left = 0
  Top = 0
  Caption = 'Form1'
  ClientHeight = 462
  ClientWidth = 131
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  OnCreate = FormCreate
  DesignSize = (
    131
    462)
  PixelsPerInch = 96
  TextHeight = 13
  object Tree1: TTree
    Left = 8
    Top = 8
    Width = 115
    Height = 446
    AllowPanning = pmNone
    Zoom.Allow = False
    TabOrder = 0
    Anchors = [akLeft, akTop, akRight, akBottom]
  end
end


unit Unit1;
interface
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComCtrls, ExtCtrls, TeeProcs, TeeTree;
type
  TForm1 = class(TForm)
    Tree1: TTree;
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation
{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
Var I: Integer;
    Node: TTreeNodeShape;
    Root: TTreeNodeShape;
Begin
   Root := Tree1.AddRoot('This is the root');
   For I := 1 To 50 Do
   Begin
      Node := Root.AddChild('This is a node text ' + IntToStr(I));
      Node.Border.Hide;
//      Node.Height := 26;
   End;
   Tree1.HorzScrollBar.Automatic := False;
End;

End.


Re: Exception when creating many nodes with icons

Posted: Thu Aug 12, 2010 3:53 pm
by yeray
Hi Mikael,
Lenfors wrote:Problem 1:
If you run it and expand the root and then click a node you can see that it moves horizontally without showing any horizontal scrollbar!
I want to disable this horizontal scrolling, I want it to be always left justified.
I think it's not possible. I've added it to the wish list to be implemented in future releases (TV52015084).
Lenfors wrote:Problem 2:
If you now uncomment the line with "Node.Height := 26;" and run the project you can see that all nodes get the text position wrong!
This is not a big issue as I'm going to custom draw all text but I dont understand why!?
When you change the Height, the AutoSize property is set to false so you'll have to also set a Width or it will be 0.