Discussion:
Function in Windowsprogram
(too old to reply)
Rene
2008-04-27 18:58:23 UTC
Permalink
Hello to all,

I am using BCB6 for a course I am taking in C++. Along with many console
applications, I have to write simple windows programs every now and again
(without having any real knowledge about windows programming in general and
not having learned about objects and stuff like that so please don't make
the answer to my question too difficult ;-) ).

Today I stumbled across a problem. I have a button on my form and am
writing the function that is executed when someone presses that button. So
far no problems. However, in that function I would like to call another
function that is outside this button function because I want to use it as
well when the user presses another button. The extra function is supposed to
update a ListBox which is named "ListBox1overzicht" (that box exists, that
is not the problem).
I have made an extra .h file in which a struct is defined and the function I
am talking about has a prototype in there as well. I will past the source of
the cpp file here:

<source code>
//---------------------------------------------------------------------------

#include <vcl.h>
#include "eigendefinitiesPC8.h"
#pragma hdrstop

#include "PC8C.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------

int huidigFormaat=0;

Spreker* lijstPointer=NULL;
Spreker* nieuweLijstPointer=NULL;

//XXXXXXXXXXXXXXXXXXXXXXXXX

//---------------------------------------------------------------------------

void __fastcall TForm1::Button1toevoegenClick(TObject *Sender)
{
nieuweLijstPointer = new Spreker[huidigFormaat+1];

for (int teller=0; teller<huidigFormaat; teller++)
{
nieuweLijstPointer[teller]=lijstPointer[teller];
}
nieuweLijstPointer[huidigFormaat].naam=this->Edit1naam->Text;
nieuweLijstPointer[huidigFormaat].telefoonnummer=this->Edit2telefoonnummer->Text;
nieuweLijstPointer[huidigFormaat].onderwerp=this->Edit3onderwerp->Text;
nieuweLijstPointer[huidigFormaat].honorarium=this->Edit4honorarium->Text.ToDouble();
huidigFormaat+=1;
delete [] lijstPointer;
lijstPointer=nieuweLijstPointer;
delete [] nieuweLijstPointer;
nieuweLijstPointer=NULL;
}
//---------------------------------------------------------------------------


void updateOverzicht(Spreker* const lijst, const int grootte)
{
this->ListBox1overzicht->Clear();
// A lot of different things will be added here later...
}

</source code>

The problem is that when I place the function declaration (function I am
talking about is called updateOverzicht) somewhere outside the
Button1toevoegenClick function (first I wanted to place it just below the
declaration of my global variables, where I put the XXXXXX's), I get the
comment that "ListBox1overzicht" is an undefined symbol. I can put any other
objects from my application in the function, they are all undefined. When I
put the function inside the Button1toevoegenClick function everything is OK.

So my question is: Where should I put those "general" functions so that they
are available from every place in the program AND the symbols are defined
instead of undefined?

Thank You very much in advance!
Yours sincerely,
Rene
Bruce Salzman
2008-04-28 00:57:45 UTC
Permalink
Post by Rene
The problem is that when I place the function declaration (function I am
talking about is called updateOverzicht) somewhere outside the
Button1toevoegenClick function (first I wanted to place it just below the
declaration of my global variables, where I put the XXXXXX's), I get the
comment that "ListBox1overzicht" is an undefined symbol. I can put any other
objects from my application in the function, they are all undefined. When I
put the function inside the Button1toevoegenClick function everything is OK.
updateOverzicht has to be a member of your form class in order for it to
access variables declared in your form. The way it is now, there is no 'this'
pointer: it is a stand-alone function.
Post by Rene
So my question is: Where should I put those "general" functions so that they
are available from every place in the program AND the symbols are defined
instead of undefined?
If you want them available everywhere, then declare them in the public section
of TForm1. Then any function can access them via the form pointer

Form1->MyFunction();

A couple other notes:
You don't need to reference this-> inside a member function. The class's
functions and variable are accessible directly.
Post by Rene
delete [] lijstPointer;
lijstPointer=nieuweLijstPointer;
delete [] nieuweLijstPointer; nieuweLijstPointer=NULL;
The statement
lijstPointer=nieuweLijstPointer;
assigns the address of an array of Spreker objects to lijstPointer. Then the
statement
delete [] nieuweLijstPointer;
deletes that array.
Now lijstPointer is left pointing to an invalid address. All you need to do is
set
nieuweLijstPointer=NULL;
--
Bruce
Jack
2008-04-28 09:42:17 UTC
Permalink
Post by Bruce Salzman
Post by Rene
The problem is that when I place the function declaration (function I am
talking about is called updateOverzicht) somewhere outside the
Button1toevoegenClick function (first I wanted to place it just below the
declaration of my global variables, where I put the XXXXXX's), I get the
comment that "ListBox1overzicht" is an undefined symbol. I can put any
other objects from my application in the function, they are all
undefined. When I put the function inside the Button1toevoegenClick
function everything is OK.
updateOverzicht has to be a member of your form class in order for it to
access variables declared in your form. The way it is now, there is no
'this' pointer: it is a stand-alone function.
Hello Bruce,

First of all, thank You very much for giving help to this newbie ;-) !

I am very much a newbie, have not learned about classes and objects yet (I
think in the course they should have postponed windows programming until we
have learned about these things) but I do have read some things about them
so I more or less understand what You mean.
Post by Bruce Salzman
Post by Rene
So my question is: Where should I put those "general" functions so that
they are available from every place in the program AND the symbols are
defined instead of undefined?
If you want them available everywhere, then declare them in the public
section of TForm1. Then any function can access them via the form pointer
Form1->MyFunction();
I guess You mean this is in the .h file, is that correct?
Post by Bruce Salzman
You don't need to reference this-> inside a member function. The class's
functions and variable are accessible directly.
To be honest with You, I do not even fully understand what this "this"
means. The design of my course is, where it comes to windows programming,
bad. I have read the text at
http://en.wikipedia.org/wiki/This_%28computer_science%29 but I do think that
I have to know very well how to work with objects and methods and stuff like
that before I will fully understand this.
Post by Bruce Salzman
Post by Rene
delete [] lijstPointer;
lijstPointer=nieuweLijstPointer;
delete [] nieuweLijstPointer; nieuweLijstPointer=NULL;
The statement
lijstPointer=nieuweLijstPointer;
assigns the address of an array of Spreker objects to lijstPointer. Then
the statement
delete [] nieuweLijstPointer;
deletes that array.
Now lijstPointer is left pointing to an invalid address. All you need to
do is set
nieuweLijstPointer=NULL;
First I was a bit puzzled by the things You wrote but after re-reading them
I understand them. By delete [] lijstPointer I have cleaned up the array I
am not using anymore. Then I tell that pointer to point toward the start of
my newly created array which I indeed delete with the next command. It is
not easy but I like this language very much and with enough practice, I'll
get there eventually (I hope ;-)).

If I may be so bold to ask another question... Is there anything that I
should do to clean up the array when I am exiting the program and if yes,
where should I put that delete command?

Thanks again!
Yours sincerely,
Rene
Rene
2008-04-28 12:34:22 UTC
Permalink
Post by Jack
Post by Bruce Salzman
If you want them available everywhere, then declare them in the public
section of TForm1. Then any function can access them via the form pointer
Form1->MyFunction();
I guess You mean this is in the .h file, is that correct?
I did this and it works, GREAT!

However, now a new question arises... I had first put the prototype of the
function in the same area of the .h file and then I get the comment that
there is a multiple declaration. When I remove the prototype, leaving the
declaration, everything is OK. Does that mean that in a Windows program
prototyping is not necessary? I tried making some silly function which I
declared after the updateOverzicht function in the .h file and had it called
from the updateOverzicht function, that caused no problems. Does the
compiler work differently when parsing the files from a windows program? I
mean, if I were making a console program, I would not be able to use a
function somewhere where it had not been declared yet. Or is it because I
put it in a .h file? Wait, I can try that out, let's make a simple console
program with a .h file. Nope, that does not work. I wrote in the .h file

void test1(int a)
{
test2(8);
}

void test2(int b)
{
}

and the compiler complains in the first function that it does not know what
test2 is. I expected it to do so just like I expected it to do so in the
windows program in which it does not complain. Is the assumption that
prototyping does not exist anymore in windows programs or is the reality
more complicated?

Thank You again in advance.
Yours sincerely,
Rene

P.S. Never mind the name "Jack", that message was written on another
computer on which a friend om mine (guess what his name is) once posted some
questions on the Borland server.
Bruce Salzman
2008-04-28 13:53:53 UTC
Permalink
Post by Rene
and the compiler complains in the first function that it does not know what
test2 is. I expected it to do so just like I expected it to do so in the
windows program in which it does not complain. Is the assumption that
prototyping does not exist anymore in windows programs or is the reality
more complicated?
No, you still need to declare something before you can use it. The .h file is
the specifies the delcarations/prototypes and the .cpp file is the
implementation. When you #include the .h file in the .cpp file, you are
prototyping all the class functions.
--
Bruce
Rene
2008-04-28 16:28:07 UTC
Permalink
Post by Bruce Salzman
Post by Rene
and the compiler complains in the first function that it does not know
what test2 is. I expected it to do so just like I expected it to do so in
the windows program in which it does not complain. Is the assumption that
prototyping does not exist anymore in windows programs or is the reality
more complicated?
No, you still need to declare something before you can use it. The .h file
is the specifies the delcarations/prototypes and the .cpp file is the
implementation. When you #include the .h file in the .cpp file, you are
prototyping all the class functions.
Now I am confused again ;-). Suppose I have the following stuff:

void calculateAverage(int, int); //declaration

void calculateAverage (int number1, int number2) //implementation
{
Edit1result->Text=AnsiString((number1 + number2)/2);
}

(Never mind what the function does, that is not important.) From what I
understood from Your first reply is that I have to put the second part (the
implementation) in the .h file of my program, otherwise the function doesn't
know what Edit1result is (problem I originally had with the ListBox). I
think that understanding is wrong. You wrote
<quote>
If you want them available everywhere, then declare them in the public
section
of TForm1. Then any function can access them via the form pointer

Form1->MyFunction();
</quote>

So I put the function implementation (now I see this is not what You told
me, I have been mixing up declaration and implementation, sorry) just behind

class TForm1 : public TForm
{
__published: // IDE-managed Components
TListBox *ListBox1overzicht;
TEdit *Edit1naam;
TLabel *Label1naam;
TEdit *Edit2telefoonnummer;
TLabel *Label2telefoonnummer;
TLabel *Label3onderwerp;
TEdit *Edit4honorarium;
TLabel *Label4honorarium;
TButton *Button1toevoegen;
TButton *Button2bijwerken;
TButton *Button3verwijderen;
TEdit *Edit3onderwerp;
void __fastcall Button1toevoegenClick(TObject *Sender);
void __fastcall Button2bijwerkenClick(TObject *Sender);
void __fastcall Button3verwijderenClick(TObject *Sender);
void __fastcall Edit1naamClick(TObject *Sender);
void __fastcall Edit2telefoonnummerClick(TObject *Sender);
void __fastcall Edit3onderwerpClick(TObject *Sender);
void __fastcall Edit4honorariumClick(TObject *Sender);
void __fastcall ListBox1overzichtClick(TObject *Sender);

private: // User declarations

public: // User declarations

in the .h file.

I really hope I am not getting on Your nerves, I try to understand but at
the moment it is still a bit unclear for me.

Wait a minute, I have an idea that might help clear things up. Below this I
will paste both an empty .cpp and an empty .h file, I would appreciate very
much if You could copy and past the function I made above into those files
in the right way so that the function will know what the Editbox is.

<EMPTY .CPP FILE>
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
</EMPTY .CPP FILE>

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

<EMPTY .H FILE>
//---------------------------------------------------------------------------

#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published: // IDE-managed Components
private: // User declarations
public: // User declarations
__fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
</EMPTY .H FILE>

Thank You for Your patience/understanding.

Yours sincerely,
Rene
Bruce Salzman
2008-04-28 18:31:51 UTC
Permalink
Post by Rene
void calculateAverage(int, int); //declaration
void calculateAverage (int number1, int number2) //implementation
{
Edit1result->Text=AnsiString((number1 + number2)/2);
}
(Never mind what the function does, that is not important.) From what I
understood from Your first reply is that I have to put the second part (the
implementation) in the .h file of my program, otherwise the function doesn't
know what Edit1result is (problem I originally had with the ListBox). I
<quote>
If you want them available everywhere, then declare them in the public section
of TForm1. Then any function can access them via the form pointer
Form1->MyFunction();
</quote>
So I put the function implementation (now I see this is not what You told
me, I have been mixing up declaration and implementation, sorry) just behind
class TForm1 : public TForm
{
__published: // IDE-managed Components
TListBox *ListBox1overzicht;
TEdit *Edit1naam;
TLabel *Label1naam;
TEdit *Edit2telefoonnummer;
TLabel *Label2telefoonnummer;
TLabel *Label3onderwerp;
TEdit *Edit4honorarium;
TLabel *Label4honorarium;
TButton *Button1toevoegen;
TButton *Button2bijwerken;
TButton *Button3verwijderen;
TEdit *Edit3onderwerp;
void __fastcall Button1toevoegenClick(TObject *Sender);
void __fastcall Button2bijwerkenClick(TObject *Sender);
void __fastcall Button3verwijderenClick(TObject *Sender);
void __fastcall Edit1naamClick(TObject *Sender);
void __fastcall Edit2telefoonnummerClick(TObject *Sender);
void __fastcall Edit3onderwerpClick(TObject *Sender);
void __fastcall Edit4honorariumClick(TObject *Sender);
void __fastcall ListBox1overzichtClick(TObject *Sender);
private: // User declarations
public: // User declarations
in the .h file.
I really hope I am not getting on Your nerves, I try to understand but at
the moment it is still a bit unclear for me.
Wait a minute, I have an idea that might help clear things up. Below this I
will paste both an empty .cpp and an empty .h file, I would appreciate very
much if You could copy and past the function I made above into those files
in the right way so that the function will know what the Editbox is.
OK, try this

<EMPTY .H FILE>
//---------------------------------------------------------------------------

#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published: // IDE-managed Components
// all the stuff the IDE puts here (don't edit the __published section)
private: // User declarations
void calculateAverage(int, int); // declare your function here
// so that it has access to the Edit control
// (could also be in the public section if necessary)
public: // User declarations
__fastcall TForm1(TComponent* Owner);
__fastcall ~TForm1(); // optionally declare a destructor
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
</EMPTY .H FILE>

<EMPTY .CPP FILE>
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}

__fastcall TForm1::~TForm1()
{
// here is where you can delete any allocated variables on exit (when the
form is destroyed)
}

void TForm1::calculateAverage (int number1, int number2) //implementation
{
Edit1result->Text=AnsiString((number1 + number2)/2);
}

//---------------------------------------------------------------------------
</EMPTY .CPP FILE>

I put the declaration of your function in the private section. This is fine as
long as it is called from another TForm1 member function. If you need to call
it from outside (say from another form) it would need to be public. Then it
can be called like this:
TForm1->calculateAverage (1,2) ;
--
Bruce
Rene
2008-04-29 14:01:31 UTC
Permalink
Post by Bruce Salzman
Post by Rene
Wait a minute, I have an idea that might help clear things up. Below this
I will paste both an empty .cpp and an empty .h file, I would appreciate
very much if You could copy and past the function I made above into those
files in the right way so that the function will know what the Editbox
is.
OK, try this
I am going to try it right away!
Post by Bruce Salzman
<EMPTY .H FILE>
//---------------------------------------------------------------------------
#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published: // IDE-managed Components
// all the stuff the IDE puts here (don't edit the __published section)
private: // User declarations
void calculateAverage(int, int); // declare your function here
// so that it has access to the Edit control
// (could also be in the public section if necessary)
public: // User declarations
__fastcall TForm1(TComponent* Owner);
__fastcall ~TForm1(); // optionally declare a destructor
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
</EMPTY .H FILE>
<EMPTY .CPP FILE>
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
__fastcall TForm1::~TForm1()
{
// here is where you can delete any allocated variables on exit (when
the form is destroyed)
}
I see. I will add that as well. As You saw in my original post, I use two
pointers to arrays that replace each other when a resize is necessary, later
on the one with the "old" size gets deleted. So normally, only
"lijstPointer" points to an array, so I guess that putting "delete []
lijstPointer" should do the job. But is there a garantee that the closing of
the program will not happen when the swapping process is going on, when
momentarily two arrays exist?

You wrote "you can delete any allocated variables ", does that mean that I
have to delete integers and stuff like that (I mean primitive variables) as
well?
Post by Bruce Salzman
void TForm1::calculateAverage (int number1, int number2) //implementation
{
Edit1result->Text=AnsiString((number1 + number2)/2);
}
//---------------------------------------------------------------------------
</EMPTY .CPP FILE>
I put the declaration of your function in the private section. This is
fine as long as it is called from another TForm1 member function. If you
need to call it from outside (say from another form) it would need to be
TForm1->calculateAverage (1,2) ;
Hi Bruce,

This does the trick! I felt very embarrassed yesterday to be asking the same
thing over and over again and was a bit worried that this would be getting
on Your nerves but I just did not get it, Your example helped me very much,
now I know the layout of my program is the way it is supposed to be. I am
going to add a search function now.

Thanks again for the help, it is highly appreciated.

Yours sincerely,
Rene
Bruce Salzman
2008-04-29 15:05:00 UTC
Permalink
Post by Rene
I see. I will add that as well. As You saw in my original post, I use two
pointers to arrays that replace each other when a resize is necessary, later
on the one with the "old" size gets deleted. So normally, only
"lijstPointer" points to an array, so I guess that putting "delete []
lijstPointer" should do the job. But is there a garantee that the closing of
the program will not happen when the swapping process is going on, when
momentarily two arrays exist?
Don't worry, there is a single execution thread that processes the events in a
typical Windows program. The message loop calls your procedures one at a time,
so a close event waits in the message queue until any currently executing
procedure ends.
Post by Rene
You wrote "you can delete any allocated variables ", does that mean that I
have to delete integers and stuff like that (I mean primitive variables) as
well?
Only things that you allocate with "new".
Post by Rene
This does the trick! I felt very embarrassed yesterday to be asking the same
thing over and over again and was a bit worried that this would be getting
on Your nerves but I just did not get it, Your example helped me very much,
now I know the layout of my program is the way it is supposed to be. I am
going to add a search function now.
Thanks again for the help, it is highly appreciated.
You're welcome. :^)
--
Bruce
Bruce Salzman
2008-04-28 13:31:50 UTC
Permalink
Post by Jack
Post by Bruce Salzman
If you want them available everywhere, then declare them in the public
section of TForm1. Then any function can access them via the form pointer
Form1->MyFunction();
I guess You mean this is in the .h file, is that correct?
Post by Bruce Salzman
You don't need to reference this-> inside a member function. The class's
functions and variable are accessible directly.
To be honest with You, I do not even fully understand what this "this"
means. The design of my course is, where it comes to windows programming,
bad. I have read the text at
http://en.wikipedia.org/wiki/This_%28computer_science%29 but I do think that
I have to know very well how to work with objects and methods and stuff like
that before I will fully understand this.
Well, your questions are really more about the C++ language than Windows.
C++ classes are normally declared in a .h file, where you put the class's
variables and functions. These things declared in the class are called
members. The member functions are defined in one or more .cpp files. The .cpp
file(s) include the .h file to get the class definition (prototypes). C++
passes an extra parameter in each member function call that points to the
class object it is operating on (this pointer).
Post by Jack
If I may be so bold to ask another question... Is there anything that I
should do to clean up the array when I am exiting the program and if yes,
where should I put that delete command?
Yes, you should delete anything you allocate with new. Declare a destructor
for your form and delete the array there. Put it right after the constructor
in the .h file.
~TForm1();

Then in the .cpp file:
TForm1::~TForm1()
{
delete [] lijstPointer;
}

Don't let this next bit confuse you, but I'll mention it because your are
using Builder's VCL.
The exception the delete rule (there is always an exception) is if you give
ownership of an object to another class. Then that class is responsible for
deleting the object. The TForm class does this with all the child controls
that are placed on it. You can also create child controls with new and specify
the form via the Owner parameter. In that case, you wouldn't delete the child
control as the form will do it in it's destructor.
--
Bruce
Rene
2008-04-28 16:00:47 UTC
Permalink
Post by Bruce Salzman
Post by Jack
Post by Bruce Salzman
If you want them available everywhere, then declare them in the public
section of TForm1. Then any function can access them via the form pointer
Form1->MyFunction();
I guess You mean this is in the .h file, is that correct?
Post by Bruce Salzman
You don't need to reference this-> inside a member function. The class's
functions and variable are accessible directly.
To be honest with You, I do not even fully understand what this "this"
means. The design of my course is, where it comes to windows programming,
bad. I have read the text at
http://en.wikipedia.org/wiki/This_%28computer_science%29 but I do think
that I have to know very well how to work with objects and methods and
stuff like that before I will fully understand this.
Well, your questions are really more about the C++ language than Windows.
C++ classes are normally declared in a .h file, where you put the class's
variables and functions. These things declared in the class are called
members. The member functions are defined in one or more .cpp files. The
.cpp file(s) include the .h file to get the class definition (prototypes).
C++ passes an extra parameter in each member function call that points to
the class object it is operating on (this pointer).
Post by Jack
If I may be so bold to ask another question... Is there anything that I
should do to clean up the array when I am exiting the program and if yes,
where should I put that delete command?
Yes, you should delete anything you allocate with new. Declare a
destructor for your form and delete the array there. Put it right after
the constructor in the .h file.
~TForm1();
TForm1::~TForm1()
{
delete [] lijstPointer;
}
Don't let this next bit confuse you, but I'll mention it because your are
using Builder's VCL.
The exception the delete rule (there is always an exception) is if you
give ownership of an object to another class. Then that class is
responsible for deleting the object. The TForm class does this with all
the child controls that are placed on it. You can also create child
controls with new and specify the form via the Owner parameter. In that
case, you wouldn't delete the child control as the form will do it in it's
destructor.
Hello again Bruce,

And thanks again Bruce. I think the things You describe will be easier for
me to understand in a couple of weeks when classes are the subject of my
course, at the moment I know what You are talking about but really
implemting the things You mention is a bit above me at the moment.

Yours sincerely,
Rene
Loading...