Solved

TabControl and Saving Info

Posted on 2004-04-16
20
353 Views
Last Modified: 2010-04-05
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
0
Comment
Question by:xpher
  • 9
  • 6
  • 5
20 Comments
 
LVL 17

Expert Comment

by:mokule
ID: 10841033
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
 
LVL 22

Expert Comment

by:Ferruccio Accalai
ID: 10841104
then to refresh the statusbar.text

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

Author Comment

by:xpher
ID: 10841107
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
Free Tool: Postgres Monitoring System

A PHP and Perl based system to collect and display usage statistics from PostgreSQL databases.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
LVL 17

Expert Comment

by:mokule
ID: 10841111
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
 
LVL 1

Author Comment

by:xpher
ID: 10841116
Should also have said I dont want the Edit text to be the tab caption, sorry.
0
 
LVL 17

Expert Comment

by:mokule
ID: 10841140
I must say I'm a little bit lost about Your intensions.
0
 
LVL 22

Expert Comment

by:Ferruccio Accalai
ID: 10841143
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
 
LVL 1

Author Comment

by:xpher
ID: 10841160

procedure TForm1.Button1Click(Sender: TObject);
var
0
 
LVL 1

Author Comment

by:xpher
ID: 10841164
Ignore last comment I pressed a key and it sent it!
I'm just trying to show you wahat I'm doing
0
 
LVL 22

Expert Comment

by:Ferruccio Accalai
ID: 10841174
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
 
LVL 17

Expert Comment

by:mokule
ID: 10841185
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
 
LVL 1

Author Comment

by:xpher
ID: 10841209
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
 
LVL 17

Expert Comment

by:mokule
ID: 10841323

No need to insert to ini. Just write all texts as I posted earlier.
0
 
LVL 1

Author Comment

by:xpher
ID: 10841393
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
 
LVL 1

Author Comment

by:xpher
ID: 10841422
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
 
LVL 17

Accepted Solution

by:
mokule earned 125 total points
ID: 10841509
Where are the texts You want to save? Are they all in StatusBar.Panels or only in TabControl.Tabs?
0
 
LVL 1

Author Comment

by:xpher
ID: 10841517
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
 
LVL 22

Expert Comment

by:Ferruccio Accalai
ID: 10841518
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
 
LVL 1

Author Comment

by:xpher
ID: 10841680
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
 
LVL 22

Assisted Solution

by:Ferruccio Accalai
Ferruccio Accalai earned 125 total points
ID: 10841719
OK for me :)
0

Featured Post

Active Directory Webinar

We all know we need to protect and secure our privileges, but where to start? Join Experts Exchange and ManageEngine on Tuesday, April 11, 2017 10:00 AM PDT to learn how to track and secure privileged users in Active Directory.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
When I am typing into a TEdit last word repeats 7 148
error 1.1 400 Bad request idhttp delphi 18 152
Correct Component for Shopping Cart. 2 113
delphi parse string to params 3 137
In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech. SAPI Installation First you need to install the SAPI type library, th…
Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…

821 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question