TabControl and Saving Info

I have a TabControl, a StatusBar, a button and a TEdit.

When I click the button I insert (not add) a Tab and the StatusBar text equals the Edit text.

How can I store and retrieve the StatusBar text for each tab. Ideally I dont want to reference it by the Tab Caption.

Also when my app starts there are no tabs created until button clicked.

Many thanks
LVL 1
xpherAsked:
Who is Participating?
 
mokuleConnect With a Mentor Commented:
Where are the texts You want to save? Are they all in StatusBar.Panels or only in TabControl.Tabs?
0
 
mokuleCommented:
Hi,
this examples inserts Tab befor currently selected one.

procedure TForm1.Button1Click(Sender: TObject);
begin
  StatusBar1.Panels[0].Text := Edit1.Text;
  if TabControl1.TabIndex < 0 then
    TabControl1.Tabs.Add(Edit1.Text)
  else
    TabControl1.Tabs.Insert(TabControl1.TabIndex,Edit1.Text);
end;
0
 
Ferruccio AccalaiSenior developer, analyst and customer assistance Commented:
then to refresh the statusbar.text

procedure TForm1.TabControl1Change(Sender: TObject);
begin
statusbar1.Panels[0].text := tabcontrol1.Tabs[tabcontrol1.tabindex];
end;
0
Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

 
xpherAuthor Commented:
Thanks 4 that. I can do the inserting it's saving and retrieving StatusBar text that's my problem. I've tried saving to an IniFile and then using TStringList to insert into and read back to inifile but without success.
0
 
mokuleCommented:
If You also want to create panels in StatusBar

procedure TForm1.Button1Click(Sender: TObject);
var
  t: TStatusPanel;
begin
  if TabControl1.TabIndex < 0 then
    begin
    TabControl1.Tabs.Add(Edit1.Text);
    StatusBar1.Panels.Add;
    StatusBar1.Panels[0].Text := Edit1.Text;
    end
  else
    begin
    TabControl1.Tabs.Insert(TabControl1.TabIndex,Edit1.Text);
    t := TStatusPanel.Create(StatusBar1.Panels);
    StatusBar1.Panels.AddItem(t,TabControl1.TabIndex-1);
    StatusBar1.Panels[TabControl1.TabIndex-1].Text := Edit1.Text;
    end;
end;
0
 
xpherAuthor Commented:
Should also have said I dont want the Edit text to be the tab caption, sorry.
0
 
mokuleCommented:
I must say I'm a little bit lost about Your intensions.
0
 
Ferruccio AccalaiSenior developer, analyst and customer assistance Commented:
So maybe you must explain better what do you need....
It seems that you're using a StatusBar to store some infos about tabcontrol.tabs and try to retrieve and recreate tabs on application start...
How do you store strings to statusbar? new panel for new tab? and how are you naming the tabs?

Please explain....
0
 
xpherAuthor Commented:

procedure TForm1.Button1Click(Sender: TObject);
var
0
 
xpherAuthor Commented:
Ignore last comment I pressed a key and it sent it!
I'm just trying to show you wahat I'm doing
0
 
Ferruccio AccalaiSenior developer, analyst and customer assistance Commented:
btw here's an example to save and reload your statusbar....

procedure TForm1.Button1Click(Sender: TObject); //save statusbar
var
  MemStr : TMemoryStream;
begin
  MemStr := TMemoryStream.Create;
  try
        MemStr.WriteComponent(StatusBar1);
    memSTr.SaveToFile('c:\MyStatusBar.dat');
  finally
    MemStr.Free;
  end;
end;

procedure TForm1.Button2Click(Sender: TObject); //load statusbar
var
MemStr : TMemoryStream;
begin
MemStr:= TMemoryStream.Create;
  try
    MemStr.LoadFromFile('c:\MyStatusBar.dat');
    MemStr.ReadComponent(StatusBar1);
  finally
    MemStr.Free;
  end;
end;

You can do the same for the Tabcontrol too
0
 
mokuleCommented:
Saving Texts from StatusBar to INI

var
  Cfg: TIniFile;
  i: integer;
begin
  Cfg := TIniFile.Create('xxx.ini');
  Cfg.WriteInteger('Texts','Count',StatusBar1.Panels.Count);
  for i := 0 to StatusBar1.Panels.Count-1 do
    begin
    Cfg.WriteString('Texts',IntToStr(i),StatusBar1.Panels[i].Text);
    end;
  Cfg.Free;
end;
0
 
xpherAuthor Commented:
This is the idea

tc1 is TabControl
sbIni is IniFile allready created

procedure TForm1.Button1Click(Sender: TObject);
var
  i: integer;
begin
  i := tc1.TabIndex;
  if i < 0 then
    tc1.Tabs.Add('New')
  else
    tc1.Tabs.Insert(1+1,'New');
  tc1.TabIndex := i+1;
  StatusBar1.SimpleText := Edit1.Text;
  //somehow need to insert not add to inifile
  sbIni.WriteString('SBTEXT', inttostr(tc1.TabIndex), Edit1.Text);
end;

procedure TForm1.tc1Change(Sender: TObject);
begin
  //this is where I need to be able to read which StatusBar text
end;

IniFIle looks:

[SBTEXT]
0=One Text
1=Two Text
2=Three Text

Now if I try to insert lets say new tabindex becomes 2 then IniFIle should look like:
[SBTEXT]
0=One Text
1=Two Text
2=Four Text
3=Three Text

0
 
mokuleCommented:

No need to insert to ini. Just write all texts as I posted earlier.
0
 
xpherAuthor Commented:
that won't work, just tried it by inserting two tabs, this is the output:
[Texts]
Count=1
0=Untitled2

I need the output to be as I mentioned earlier. Ive read a help file about loading into stringlist, manipulating data and saving back to inifile, but I just keep getting errors.
0
 
xpherAuthor Commented:
Changed your code to this:

Cfg := TIniFile.Create('xxx.ini');
  Cfg.WriteInteger('Texts','Count',StatusBar1.Panels.Count);
  for i := 0 to StatusBar1.Panels.Count-1 do
    begin
    Cfg.WriteString('Texts',inttostr(tc1.TabIndex),StatusBar1.Panels[i].Text);
    end;
  Cfg.Free;

If I add insert 3 tabs the output is:
[Texts]
Count=1
0=Untitled1
1=Untitled2
2=Untitled3

Now if I insert between 1 and 2:
[Texts]
Count=1
0=Untitled1
1=Untitled2
2=Untitled4

It is replacing and not inserting in inifile
0
 
xpherAuthor Commented:
I can get it to work using a ListBox but would rather not, like so. (Try inserting a tab between tabs and you will see what I mean):

******************************

unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    tc1: TTabControl;
    StatusBar1: TStatusBar;
    Button1: TButton;
    ListBox1: TListBox;
    procedure Button1Click(Sender: TObject);
    procedure tc1Change(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}
var
  x: integer = 1;

procedure TForm1.Button1Click(Sender: TObject);
var
  i: integer;
begin
  i := tc1.TabIndex;
  if i < 0 then
    tc1.Tabs.Add('Untitled' + IntToStr(x))
  else
    tc1.Tabs.Insert(i+1,'Untitled' + IntToStr(x));
  tc1.TabIndex := i+1;
  StatusBar1.Panels[0].Text := 'Text for Untitled' + IntToStr(x);
  //somehow need to insert not add to inifile
  ListBox1.Items.Insert(tc1.TabIndex, StatusBar1.Panels[0].Text);
  x := x + 1;
end;

procedure TForm1.tc1Change(Sender: TObject);
var
  i: integer;
begin
  StatusBar1.Panels[0].Text := ListBox1.Items.Strings[tc1.TabIndex];
end;

end.
0
 
Ferruccio AccalaiSenior developer, analyst and customer assistance Commented:
OK here's my version....

try it and tell about it....

unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    tc1: TTabControl;
    StatusBar1: TStatusBar;
    Button1: TButton;
    Edit1: TEdit;
    procedure tc1Change(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  sbIni : TInifile;
  list: TStringlist;
implementation

{$R *.dfm}

procedure TForm1.tc1Change(Sender: TObject);
begin
statusbar1.simpletext := list[tc1.tabindex];
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  i: integer;
begin
  i := tc1.TabIndex;
  if (i < 0) then begin
    tc1.Tabs.Add('New');
    list.Add(edit1.text);
  end else begin
    list.insert(i,edit1.text);
    tc1.Tabs.Insert(1+1,'New');
  end;

  tc1change(tc1);
end;
procedure TForm1.FormCreate(Sender: TObject);
var
i: Integer;
begin
sbIni := Tinifile.Create(extractfilepath(application.exename)+'sbIni.ini');
list := TStringlist.Create;
sbini.ReadSectionValues('SBTEXT',list);
for  i := 0 to list.count-1 do
  begin
    List[i] := copy(list[i],pos('=',list[i])+1,length(list[i])-pos('=',list[i])+1);
    tc1.Tabs.Add('New');
  end;
  tc1change(tc1);
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
var
i: Integer;
begin
for i := 0 to list.Count-1 do
sbini.WriteString('SBTEXT',inttostr(i),list[i]);
sbini.Free;
list.Free;
end;

end.
0
 
xpherAuthor Commented:
I was just gonna post and say I'd sorted it out. My problem was I was creating StringList everytime button clicked which seemed to be causing error. Your solution puts the text into StatusBar in wrong order after clicking through tabs, it is displayed in reverse order.

This is how I've done it now:
implementation

{$R *.dfm}
var
  x: integer = 1;  sl: tstringlist;

procedure TForm1.Button1Click(Sender: TObject);
var
  i: integer;
begin
  i := tc1.TabIndex;
  if i < 0 then
    tc1.Tabs.Add('Untitled' + IntToStr(x))
  else
    tc1.Tabs.Insert(i+1,'Untitled' + IntToStr(x));
  tc1.TabIndex := i+1;
  StatusBar1.Panels[0].Text := 'Text for Untitled' + IntToStr(x);
  sl.Insert(tc1.TabIndex, StatusBar1.Panels[0].Text);
  for i := 0 to sl.Count - 1 do
  myini.WriteString('MINE', inttostr(i), sl.strings[i]);
  x := x + 1;
end;

procedure TForm1.tc1Change(Sender: TObject);
var
  i: integer;
begin
  StatusBar1.Panels[0].Text := sl.Strings[tc1.tabindex];
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  sl := tstringlist.Create;
  myini := tinifile.Create('xxx.ini');
end;

Many thanks for both of your time and effort, sometimes I think it just helps to communicate an idea to see the problem.

If both of you have no objection I'd like to split points between you if that's OK.

Cheers
0
 
Ferruccio AccalaiConnect With a Mentor Senior developer, analyst and customer assistance Commented:
OK for me :)
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.