[Builder 6] Save Label content to .txt file

Pages: 123
I tried on C disc and still nothing.
Try this:
1
2
3
4
TIniFile *IniFile;
IniFile = new TIniFile("Filename");
if (!FileExists("Filename")
   RaiseLastOSError();


I am not sure what namespace RaiseLastOSError is in.
You mean that I should use it in OnClose method?
Common practice is to declare TIniFile *IniFile; in the Form class and create it in the OnCreate method. In OnClose you delete it.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
 
#include <IniFiles.hpp> //TIniFile
 
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
  : TForm(Owner)
{
  TIniFile *IniFile;
  IniFile = new TIniFile("Filename");
  if (!FileExists("Filename"))
      RaiseLastOSError();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
  seconds++;

  Label1->Caption = FormatSeconds(seconds);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::OnClose(TObject *Sender, TCloseAction &Action)
{
  TIniFile *IniFile;
  IniFile = new TIniFile("C:\\timer.ini");
  IniFile->WriteInteger("Timer","seconds",seconds);
  delete IniFile;
}
//---------------------------------------------------------------------------
 
AnsiString TForm1::FormatSeconds(int sec)
{
  int hrs, mins, secs;
  AnsiString retVal;
 
  hrs = sec / 3600;
  mins = (sec - hrs * 3600) / 60;
  secs = sec - hrs * 3600 - mins * 60;
 
  retVal.printf("%02d:%02d:%02d",hrs,mins,secs);
  return retVal;
}
//--------------------------------------------------------------------------- 

And I have such warning: 'IniFile' is assigned a value that is never used
1
2
3
4
5
6
7
8
__fastcall TForm1::TForm1(TComponent* Owner)
  : TForm(Owner)
{
  TIniFile *IniFile;
  IniFile = new TIniFile("Filename");
  if (!FileExists("Filename"))
      RaiseLastOSError();
}


You create a local variable in your constructor, but don't use it.
So I have to change this method to be like this?
1
2
3
4
5
6
7
void __fastcall TForm1::OnClose(TObject *Sender, TCloseAction &Action)
{
  TIniFile *IniFile;
  IniFile = new TIniFile("Filename");
  IniFile->WriteInteger("Timer","seconds",seconds);
  delete IniFile;
}
Not really, you are still using local variables. Better declare it as a form variable.
1
2
3
4
5
class TForm1 : public TForm
{
private:
   TIniFile *FIni;
};

Create FIni in the constructor
1
2
3
4
5
6
__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner)
{
  FIniFile =  new TIniFile("Filename");
  if (!FileExists("Filename"))
      RaiseLastOSError();
}

Delete it in the OnClose event.
1
2
3
4
5
void __fastcall TForm1::OnClose(TObject *Sender, TCloseAction &Action)
{
  FIni->WriteInteger("Timer","seconds",seconds);
  delete FIni;
}
1
2
3
4
5
class TForm1 : public TForm
{
private:
   TIniFile *FIni;
};

This should be in .h file?
Normally yes, if you have your class declaration there.
So my .h file should look like this?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
//---------------------------------------------------------------------------
#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <ExtCtrls.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
private:
   TIniFile *FIni;
__published:    // IDE-managed Components
  TLabel *Label1;
  TTimer *Timer1;
  void __fastcall Timer1Timer(TObject *Sender);
  void __fastcall OnClose(TObject *Sender, TCloseAction &Action);
private:    // User declarations
  int seconds;
 
  AnsiString FormatSeconds(int sec);
public:        // User declarations
  __fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif 
Yes, looks fine.
project file:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
 
#include <IniFiles.hpp> //TIniFile
 
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
  : TForm(Owner)
{
  TIniFile *IniFile;
  IniFile = new TIniFile("C:\\timer.ini");
  seconds = IniFile->ReadInteger("Timer","seconds",0);
  delete IniFile;
 
  Label1->Caption = FormatSeconds(seconds);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
  seconds++;
 
  Label1->Caption = FormatSeconds(seconds);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::OnClose(TObject *Sender, TCloseAction &Action)
{
  TIniFile *IniFile;
  IniFile = new TIniFile("C:\\timer.ini");
  IniFile->WriteInteger("Timer","seconds",seconds);
  delete IniFile;
}
//---------------------------------------------------------------------------
 
AnsiString TForm1::FormatSeconds(int sec)
{
  int hrs, mins, secs;
  AnsiString retVal;
 
  hrs = sec / 3600;
  mins = (sec - hrs * 3600) / 60;
  secs = sec - hrs * 3600 - mins * 60;
 
  retVal.printf("%02d:%02d:%02d",hrs,mins,secs);
  return retVal;
}
//--------------------------------------------------------------------------- 


.h as in above post

Program can run. It counts but it doesn't save the file. There's nothing in C disc.
IniFile = new TIniFile("C:\\timer.ini");
I thought you were using a different location ?
I tried to save this on D disc but still nothing.
Wait, my project file should be like above or like this?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
 
#include <IniFiles.hpp> //TIniFile
 
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner)
{
  FIniFile =  new TIniFile("Filename");
  if (!FileExists("Filename"))
      RaiseLastOSError();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
  seconds++;
 
  Label1->Caption = FormatSeconds(seconds);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::OnClose(TObject *Sender, TCloseAction &Action)
{
  FIni->WriteInteger("Timer","seconds",seconds);
  delete FIni;
}
//---------------------------------------------------------------------------
 
AnsiString TForm1::FormatSeconds(int sec)
{
  int hrs, mins, secs;
  AnsiString retVal;
 
  hrs = sec / 3600;
  mins = (sec - hrs * 3600) / 60;
  secs = sec - hrs * 3600 - mins * 60;
 
  retVal.printf("%02d:%02d:%02d",hrs,mins,secs);
  return retVal;
}
//--------------------------------------------------------------------------- 

I tried this and I have error: "Undefined symbol 'FIniFile'
That's because you haven't defined the symbol FIniFile. You should probably do that.
closed account (48bpfSEw)
Another solution of extracting label-captions is to parse the DFM-File!
Another solution of extracting label-captions is to parse the DFM-File!

@Necip,
you are really a master in finding the most complicated solution.
closed account (48bpfSEw)
@Thomas, we are not in the beginner section...
closed account (48bpfSEw)
This is my little function which "parses" (indeed it searches for patterns) to find all "Properties.OnEditValueChanged" in a DFM file. Read the file first in MemoIn then call this function. It needs a TMemo* MemoOut in the form.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
void TForm1::Search (std::string& strFileName) {
  std::stack<std::string>   mystack;
  std::string strObject     = "object";
  std::string strInline     = "inline";
  std::string strInherited  = "inherited";

  std::string strProperties = "Properties.OnEditValueChanged";
  std::string strEnd        = "end";
  std::string strSeparator  = "|";
  std::string strToken;

  int iCount  = MemoIn->Lines->Text.Length();
  for (int idx = 1; idx <= iCount; ++idx) {
    char c = MemoIn->Lines->Text[idx];

    Application->ProcessMessages();

    if (c == ' ' || c == 13 || c == 10) {
      if (strToken == strObject    ||
          strToken == strInline    ||
          strToken == strInherited ||
          strToken == strProperties) {
        std::string strRest = strFileName + strSeparator + strToken + strSeparator;
        for (++idx; idx <= iCount; ++idx) {
          char c = MemoIn->Lines->Text[idx];
          if (c == 13 || c == 10)
            break;
          strRest += c;
          }

        if (strToken == strObject ||
            strToken == strInline ||
            strToken == strInherited)
          mystack.push(strRest);
        else {
          if (mystack.size()) {
            std::string s = mystack.top() + strSeparator + strRest;
            mystack.pop();
            MemoOut->Lines->Add(s.c_str());
            }
          }

        strToken.clear();
        }
      else if (strToken == strEnd) {
        if (mystack.size()) {
          std::string s = mystack.top();
          mystack.pop();
          MemoOut->Lines->Add(s.c_str());
          }
        }

      strToken.clear();
      continue;
      }

    else if (c == '{') {
      for (++idx; idx <= iCount; ++idx) {
        char c = MemoIn->Lines->Text[idx];
        if (c == '}')
          break;
        }
      ++idx;
      continue;
      }

    strToken += c;
    }

  return;
}
Last edited on
Pages: 123