Board index » delphi » Assigning a Pointer to TStringList.Items to ListBox Items

Assigning a Pointer to TStringList.Items to ListBox Items

I want to assigning a pointer to a TStringList.Items array to ListBox.Items array without copying the items.

Is it possible to make one items array point to another with the idea of refreshing the listbox after making the Items property point to a different
TStrings array (e.g. Items in a TStringList)?

If so, how?

Thanks.
Raymond Kennington

 

Re:Assigning a Pointer to TStringList.Items to ListBox Items


Quote
In article <3BEDB357.C3F6...@chariot.net.au>, Raymond Kennington wrote:
> I want to assigning a pointer to a TStringList.Items array to ListBox.Items array without copying the items.

You have to copy the items because the TListBox is merely a thing wrapper around the underlying windows
control and the latter actually manages the strings. It is quite easy though:

  ListBox.Items.Assign(StringList);

Mike Orriss (TeamB and DevExpress)

Re:Assigning a Pointer to TStringList.Items to ListBox Items


Thanks.

Suppose there are 100 StringLists with 2000 strings with Objects (that use lots of memory) attached to each string. I don't want to copy the objects.

Suppose further that these StringLists are to appear on the screen in a single ListBox one list at a time. The ListBox manages insertions and
deletions, but I don't want to duplicate these in the ListBox by overriding the methods. This duplicates the time required, especially for sorting,
for example.

So it looks like I'll have to have 100 listBoxes and display each one in turn instead.

Is there a better way?

Raymond.

Re:Assigning a Pointer to TStringList.Items to ListBox Items


Quote
In article <3BEDB357.C3F6...@chariot.net.au>, Raymond Kennington wrote:

> I want to assigning a pointer to a TStringList.Items array to
> ListBox.Items array without copying the items.

Not possible. You have to understand that TListbox is just a wrapper around a
standard Windows control. The listbox control stores the strings it displays
internally (in Windows code), the Items property just gives you Tstrings-style
access to these internally stored items, it does not have any VCl-level storage
space for the items.

Quote

> Is it possible to make one items array point to another with the idea
> of refreshing the listbox after making the Items property point to a
> different TStrings array (e.g. Items in a TStringList)?

Wellll, the listbox control has a "virtual" mode in Win32. The D6 TListbox
class has support for this mode build in. Look at the OnData event in the
online help. You can use this mode to tie the listbox to an external list
of strings. You would still have to do some things to get the listbox to
repaint if an item changes in the external list since the listbox has no way
of getting aware of such a change.

Example for using a TListbox in virtual mode:

Create a new application, drop a Tedit, TLIstbox, 3 TButtons, 1 TActionlist
on the form. Add three actions and name them AddAction, DeleteAction,
ReplaceAction. Assign these to the three buttons. Add handlers for the actions
OnExecute and OnUpdate events. Set the listboxes Style to lbVirtual, add
handlers for the listboxes OnData and OnDatafind events. Add handlers for the
forms OnCreate and OnDestroy events. Modify the unit as below.

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ActnList, StdCtrls;

type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Button1: TButton;
    ListBox1: TListBox;
    Button2: TButton;
    Button3: TButton;
    ActionList1: TActionList;
    AddAction: TAction;
    ReplaceAction: TAction;
    DeleteAction: TAction;
    procedure AddActionUpdate(Sender: TObject);
    procedure AddActionExecute(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure DeleteActionUpdate(Sender: TObject);
    procedure DeleteActionExecute(Sender: TObject);
    procedure ReplaceActionUpdate(Sender: TObject);
    procedure ReplaceActionExecute(Sender: TObject);
    procedure ListBox1Data(Control: TWinControl; Index: Integer;
      var Data: String);
    function ListBox1DataFind(Control: TWinControl;
      FindString: String): Integer;
  private
    FTextitems: Tstringlist;
    Procedure TextItemsChange( sender: TObject );
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.AddActionUpdate(Sender: TObject);
begin
  (sender as TAction).Enabled :=
    (edit1.GetTextLen > 0) and
    (listbox1.Items.IndexOf( edit1.Text ) < 0);
end;

procedure TForm1.AddActionExecute(Sender: TObject);
begin
  FTextitems.Add( edit1.Text );
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  FTextitems := TStringlist.Create;
  FTextItems.OnChange := TextItemsChange;
end;

Procedure TForm1.TextItemsChange(sender: TObject);
Begin
  If FTextItems.Count <> listbox1.items.count Then
    listbox1.count := FTextItems.Count;
  listbox1.Invalidate;
End;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  FTextitems.Free;
end;

procedure TForm1.DeleteActionUpdate(Sender: TObject);
begin
  (Sender as TAction).Enabled := listbox1.ItemIndex >= 0;
end;

procedure TForm1.DeleteActionExecute(Sender: TObject);
begin
  FTextitems.Delete( listbox1.ItemIndex );
end;

procedure TForm1.ReplaceActionUpdate(Sender: TObject);
begin
  (Sender as TAction).Enabled :=
     AddAction.Enabled and DeleteAction.Enabled;
end;

procedure TForm1.ReplaceActionExecute(Sender: TObject);
begin
  FTextitems[ listbox1.ItemIndex ] := edit1.Text;
end;

procedure TForm1.ListBox1Data(Control: TWinControl; Index: Integer;
  var Data: String);
begin
  If (index >= 0) and ( index < FTextitems.count ) Then
    Data := FtextItems[index]
  Else
    Data := '';
end;

function TForm1.ListBox1DataFind(Control: TWinControl;
  FindString: String): Integer;
begin
  Result := FTextitems.IndexOf( Findstring );
end;

end.

Here is the finished form DFM file:

object Form1: TForm1
  Left = 239
  Top = 148
  Width = 303
  Height = 324
  Caption = 'Form1'
  Color = clBtnFace
  Font.Charset = ANSI_CHARSET
  Font.Color = clWindowText
  Font.Height = -15
  Font.Name = 'Arial'
  Font.Style = []
  OldCreateOrder = False
  Position = poDefaultSizeOnly
  Scaled = False
  OnCreate = FormCreate
  OnDestroy = FormDestroy
  PixelsPerInch = 120
  TextHeight = 17
  object Edit1: TEdit
    Left = 16
    Top = 12
    Width = 177
    Height = 25
    TabOrder = 0
    Text = 'Edit1'
  end
  object Button1: TButton
    Left = 208
    Top = 16
    Width = 75
    Height = 25
    Action = AddAction
    TabOrder = 1
  end
  object ListBox1: TListBox
    Left = 16
    Top = 52
    Width = 177
    Height = 225
    Style = lbVirtual
    ItemHeight = 16
    TabOrder = 2
    OnData = ListBox1Data
    OnDataFind = ListBox1DataFind
  end
  object Button2: TButton
    Left = 208
    Top = 56
    Width = 75
    Height = 25
    Action = DeleteAction
    TabOrder = 3
  end
  object Button3: TButton
    Left = 208
    Top = 92
    Width = 75
    Height = 25
    Action = ReplaceAction
    TabOrder = 4
  end
  object ActionList1: TActionList
    Left = 212
    Top = 128
    object AddAction: TAction
      Caption = 'Add'
      OnExecute = AddActionExecute
      OnUpdate = AddActionUpdate
    end
    object ReplaceAction: TAction
      Caption = 'Relace'
      OnExecute = ReplaceActionExecute
      OnUpdate = ReplaceActionUpdate
    end
    object DeleteAction: TAction
      Caption = 'Delete'
      OnExecute = DeleteActionExecute
      OnUpdate = DeleteActionUpdate
    end
  end
end

Peter Below (TeamB)  100113.1...@compuserve.com)
No e-mail responses, please, unless explicitly requested!
Note: I'm unable to visit the newsgroups every day at the moment,
so be patient if you don't get a reply immediately.

Re:Assigning a Pointer to TStringList.Items to ListBox Items


Quote
In article <3BEE61E2.B2428...@chariot.net.au>, Raymond Kennington wrote:
> So it looks like I'll have to have 100 listBoxes and display each one in turn instead.

> Is there a better way?

It is difficult to say without knowing exactly what you are trying to achieve. However,
presenting the user with 100 listboxes one after another sounds very heavy.

Mike Orriss (TeamB and DevExpress)

Re:Assigning a Pointer to TStringList.Items to ListBox Items


There will be lots in memory and the user will be able to choose which list is displayed in the listbox. The user could choose to show N lists at a
time.

Since each item in each list will contain an object of maybe 3 Kb it seemed like a good idea not to continually swap the lists from internal memory to
a list box.

So now I think I'll create as many list boxes as required and hide/show them by setting the parent to nil or a windowControl (yet to be decided which
one).

Will having 100 ListBoxes in memory overload Win95's resources? Or memory?

Raymond Kennington.

Quote
"Mike Orriss (TeamB)" wrote:

> In article <3BEE61E2.B2428...@chariot.net.au>, Raymond Kennington wrote:
> > So it looks like I'll have to have 100 listBoxes and display each one in turn instead.

> > Is there a better way?

> It is difficult to say without knowing exactly what you are trying to achieve. However,
> presenting the user with 100 listboxes one after another sounds very heavy.

> Mike Orriss (TeamB and DevExpress)

Re:Assigning a Pointer to TStringList.Items to ListBox Items


Quote
In article <3BEF41EF.F1EE0...@chariot.net.au>, Raymond Kennington wrote:
> Will having 100 ListBoxes in memory overload Win95's resources? Or memory?

Very likely.

Why do all listboxes need to be created first? Can't you create and destroy
as needed?

Mike Orriss (TeamB and DevExpress)

Re:Assigning a Pointer to TStringList.Items to ListBox Items


Quote
"Raymond Kennington" <raymo...@chariot.net.au> wrote in message

news:3BEF41EF.F1EE088B@chariot.net.au...
Quote
> There will be lots in memory and the user will be able to choose which

list is displayed in the listbox. The user could choose to show N lists at a
Quote
> time.

> Since each item in each list will contain an object of maybe 3 Kb it

seemed like a good idea not to continually swap the lists from internal
memory to
Quote
> a list box.

> So now I think I'll create as many list boxes as required and hide/show

them by setting the parent to nil or a windowControl (yet to be decided
which

Quote
> one).

> Will having 100 ListBoxes in memory overload Win95's resources? Or memory?

Yes it will reduce resources. Why can't you create TStringLists of each of
the variations and just use one listbox to assign them to?

Woody

Other Threads