Solved

Help with an easy C++ function

Posted on 2006-11-26
18
318 Views
Last Modified: 2013-11-17
I've just opened Borland C++ Builder v6.0 for the first time and I'm stuck :(

I used to code in Turbo Pascal and Delphi. The last couple of years I've used VB for applications a bit, but my experience is still limited.

I've tried C++ for Dummies, but it is frustrating to be stuck almost before I've started.

My problem:
Create a new unit, write a function in it and call it from the press of a button (in Unit1).
I'm still just playing around, so the function should be VERY SIMPLE, just so I can learn the framework around a function. The only requirement is that it returns a boolean value of TRUE if the function executed with success. (e.g. Show a message on the screen).

If you know how to do this, please supply my with an example of Unit1.cpp, Unit1.h, Unit2.cpp and Unit2.h

Arild
0
Comment
Question by:arildj78
  • 9
  • 6
  • 2
  • +1
18 Comments
 
LVL 16

Expert Comment

by:George Tokas
ID: 18016479
Start BCB.
Select File|New|Project....
Now Select File|SaveProjectAs...
Choose a name for unit1.cpp and project name...
It will be good to create subdirectories to hold your projects...
By default BCB is directing saves and opens to "Projects" subdirectory...
Press F9 to compile and run the project...
That was step 1...
George Tokas.
0
 
LVL 16

Expert Comment

by:George Tokas
ID: 18016489
Step 2.
Drop a TButton to your form...
Place it wherever you like and double click on it...
The cursor will be transfered to the editor under this:
void __fastcall TForm1::Button1Click(TObject *Sender)
{

}
Inside the brackets write as follows:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
    ShowMessage("Hello World");
}
Press F9 again and click on the button...
Not a real difference from Delphi...

George Tokas.
0
 
LVL 16

Expert Comment

by:George Tokas
ID: 18016493
One more suggestion...
BCB like Delphi came with a subdirectory named "Examples"
You will helped A LOT by opening and checking out some of them...

George Tokas.
0
 
LVL 2

Author Comment

by:arildj78
ID: 18018317
I've managed that part :)
The problem was not the ShowMessage but how to declare a new function (and have it in a different unit).

Arild
0
 
LVL 16

Expert Comment

by:George Tokas
ID: 18019384
There are 2 ways...
The one is to create a new unit(.cpp) and save it... Along with the cpp file a .h file is saved also...
Now you can declare your function inside the header and implement in cpp but you will not find it easy...
The second and easier way is to declare the function at the main form's header lets say unit1.h and it is the place TForm1 is declared as you can see here:
//---------------------------------------------------------------------------

#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;

You can declare your function under the private or public section as follows:
void __fastcall MyFunction();
At your other unit lets say unit2.cpp first you have to include the main header by changing the first #include to the main unit's header.
After that you implement as follows:
void __fastcall TForm1::MyFunction()//The function is member of TForm1...
{
.........//your code here.
}

Try this way first before you go further with classes...
We will be here if you need any more help...

George Tokas.
0
 
LVL 18

Expert Comment

by:JoseParrot
ID: 18021950
Hi,

You must
#include "Unit2.h"
in your Unit1.cpp code, just below the #include "Unit1.h". That way Unit1 knows who is Unit2 (I'm assuming default names as Builder creates them).

Now, in the ButtonClick function in Unit1,
void __fastcall TForm1::Button1Click(TObject *Sender)
{
       Form2->ShowModal();
}

If you have a function there, in Unit2, you can call it directly from Unit1, also access variables and components there; no need to Show Unit2 in the screen:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
       Form2->SomeFunctionThere(this);
       MyIntHere = Form2->SomeIntThere;
       MyEditHere->Text = Form2->SomeEditThere->Text;
}

Jose
0
 
LVL 16

Expert Comment

by:George Tokas
ID: 18022107
@ JoseParrot
First things first my friend...
Let first understand how the total source can be split in many units and then try add forms and use other classes...

George Tokas.
0
 
LVL 2

Author Comment

by:arildj78
ID: 18023785
Ok... so far so good. But my problem still stands.
I'm trying to create a new unit where I will put all my favorite functions. For this reason I don't want to create a second form, or write the header in Unit1. I have figured out how to make unit1 lookup unit2 to look for my new functions. Now I'm struggling with the declarations in Unit2.h

Arild
0
 
LVL 2

Author Comment

by:arildj78
ID: 18024003
Here are two examples:

Example 1
<Unit2.h>
//---------------------------------------------------------------------------
#ifndef Unit2H
#define Unit2H
bool amj(int);
#endif
//---------------------------------------------------------------------------

<Unit2.cpp>
//---------------------------------------------------------------------------
#pragma hdrstop
#include "Unit2.h"
#pragma package(smart_init)

bool amj(int x)
{if (x == 123){return true;} else {return false;}}
//---------------------------------------------------------------------------



Example 2
<Unit2.h>
//---------------------------------------------------------------------------
#ifndef Unit2H
#define Unit2H
bool amj(string);
#endif
//---------------------------------------------------------------------------

<Unit2.cpp>
//---------------------------------------------------------------------------
#pragma hdrstop
#include "Unit2.h"
#pragma package(smart_init)

bool amj(string x)
{if (x == "The Boss"){return true;} else {return false;}}
//---------------------------------------------------------------------------


Example1 runs without a hitch, but Example2 comes up with this error
[C++ Error] Unit2.h(4): E2275 { expected


What is wrong ?


Arild
0
Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

 
LVL 16

Expert Comment

by:George Tokas
ID: 18027550
>>bool amj(string);
bool amj(string x);
You declared the function with a type variable (string) but you didn't declare the variable (x) itself....

HAVE IN MIND THE FOLLOWING:
TForm1 (the form you use) is a class!
Inside this class you can use and other components from the VCL pallete...
It will be preffered and easier for you to work inside the class...
If you create another form it will be another different class and interaction between them (the forms) needs a little bit of experience on handling BCB code... Not anything tragic just understanding the way things work...

George Tokas.
0
 
LVL 2

Author Comment

by:arildj78
ID: 18029514
Still don't understand why the same code worked with int ?

I also wonder why it is a good idea to make my compilation of reusable code inside a TForm class ???  Wouldn't that be a waste of resources?   I mean, in my next project (let's say it is one with one form in it), I have one form from when the project is created. Why would I need the bits and pieces from a second form hidden among my reusable code?

Arild
0
 
LVL 16

Expert Comment

by:George Tokas
ID: 18029728
>>Still don't understand why the same code worked with int ?
Check out your previous post:
#ifndef Unit2H
#define Unit2H
bool amj(int);
#endif
This works...
#ifndef Unit2H
#define Unit2H
bool amj(string);
#endif
This NOT... Needs to be:
#ifndef Unit2H
#define Unit2H
bool amj(string x);
#endif

>>I also wonder why it is a good idea to make my compilation of reusable code inside a TForm class ???  
No it is not a good idea...
Its just to get used on how things work with BCB...
Also all reusable you will made will be visible as variables inside the exexutable...
You can understand some of the security risks there...

George Tokas.
0
 
LVL 2

Author Comment

by:arildj78
ID: 18030625
#ifndef Unit2H
#define Unit2H
bool amj(int);
#endif
This works... WHY ????

If the "string version" of the declaration need to include the variable x, why don't I need it when I declare an integer?

Arild
0
 
LVL 16

Accepted Solution

by:
George Tokas earned 400 total points
ID: 18032464
>>This works... WHY ????
Check out your posts...
>>bool amj(int x);
This works as you posted..

Also:
bool amj(int);
bool amj(int*);
bool amj(int&);

All of them are different declarations in example...
It is preffered in declaration to have and the variable ...(int x) or ...(string x)
As for details why one is working and other don't depends on how the compiler see it usually...
One of the common bugs of BCB6 even with all fixes installed is that may times it needs a full "Build Project" instead of pressing F9...
As an exact answer both:
bool amj(int);
bool amj(AnsiString);//Better that way instead if just "string"

have to work ok....
If one of them don't then something is missing somewere in the project.

George Tokas.
0
 
LVL 2

Author Comment

by:arildj78
ID: 18059040
ok...  so the fact that declaring
bool amj(string);
is not working means that something is missing somewhere in the project?
How can I find out what is missing?

My project does not contain any code at all (almost true), except for what we have discussed here.
I created a new project. Then created a second unit. In the new unit (Unit2) I wrote the following.

<Unit2.h>
//---------------------------------------------------------------------------
#ifndef Unit2H
#define Unit2H
bool amj(string);
#endif
//---------------------------------------------------------------------------

<Unit2.cpp>
//---------------------------------------------------------------------------
#pragma hdrstop
#include "Unit2.h"
#pragma package(smart_init)

bool amj(string x)
{if (x == "The Boss"){return true;} else {return false;}}
//---------------------------------------------------------------------------


Then in Unit1.cpp i wrote
#include "Unit2.h"
After that I created a button on Form1, doubleclicked it, and in the eventhandler wrote

if (    amj("The Boss")     )
       {ShowMessage("I made it !!!");}
else {ShowMessage("Bugger !!!");}


That is all I have in the project. As stated earlier this is just to figure out how I can declare and use a function in a second Unit.   Since I'm still stuck, I would be very for all help, or even a .zip file with a working project :)

Arild
0
 

Expert Comment

by:half_life_fool
ID: 18063633
I think what you need to define in Unit2:

<Unit2.h>
//---------------------------------------------------------------------------
#ifndef Unit2H
#define Unit2H
extern bool amj(string);
#endif
//---------------------------------------------------------------------------


Please let me know if that works out :)
0
 
LVL 16

Expert Comment

by:George Tokas
ID: 18064076
As I posted first of all you have to get used on how things work with BCB...
That means:
1. The form appeared each time you start a project is a CLASS...
2. The application made when you compile the project IS CLASS ORIENTED....

There was some time passed back in 1996 before I get used to it...
That is why I advised you to work inside the class.
Anyway since you and everyone of us creating a new project with a form named "form1" whatever subroutine you will made for one can be used everywere... If there is another form's part the only thing change is the "__fastcall TFormx::" section.
Of course you can do things the way you describe but it will be better to follow this advise before you continue...
Explore the way things in BCB almost like in Delphi works...

George Tokas.
0
 
LVL 18

Assisted Solution

by:JoseParrot
JoseParrot earned 100 total points
ID: 18119983
Hi, arildj78,

To make things run as you expect, you may want try and analyse the following code.

First, we create a Form, whit one TButton and two TEdit.
Builder will create the following Unit1.h (no need to modify it)

//////////  Unit1.h  ///////////////////////////////////////////////////////
//---------------------------------------------------------------------------
#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published:      // IDE-managed Components
    TButton *Button1;
    TEdit *Edit1;
    TEdit *Edit2;
    void __fastcall Button1Click(TObject *Sender);
private:      // User declarations
public:            // User declarations
    __fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
//---------------------------------------------------------------------------


Builder will create too the file Unit1.cpp, where you will add your own code, as below.

//////////  Unit1.cpp  /////////////////////////////////////////////////////
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
#include <string>       // to use typedef string
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
}
//---------------------------------------------------------------------------
using namespace std;    // need define namespace
extern bool amj(int);     // need declare external functions
extern bool amjs(string);

// and now your code to handle what happens at button click
void __fastcall TForm1::Button1Click(TObject *Sender)
{
     if (amj(123))
        Edit1->Text="OK"; else Edit1->Text="ERROR";
     if (amjs("The Boss"))
        Edit2->Text="OK"; else Edit2->Text="ERROR";
}
//---------------------------------------------------------------------------


Now you create a Unit (with File->New->Unit).
Save it as Unit2.h and Unit2.cpp (by the way these are default names...)
Unit2.h should be:
////////// Unit2.h  ////////////////////////////////////////////////////////
//---------------------------------------------------------------------------
#ifndef Unit2H
#define Unit2H

#include<string>           // to use string
using namespace std;    // to define namespace
bool  amj(int);              // functions prototipes
bool  amjs(string);

#endif
//---------------------------------------------------------------------------

And the code for your functions in Unit2.cpp:
////////// Unit2.cpp  /////////////////////////////////////////////////////
//---------------------------------------------------------------------------
#pragma hdrstop
#include "Unit2.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)

bool amj(int x)
{if (x == 123){return true;} else {return false;}}

bool amjs(string sx)
{if (sx == "The Boss"){return true;} else {return false;}}
//---------------------------------------------------------------------------


After execution, both Edits should display:
OK OK

That solution isn't as sophisticated as that one our guru George Tokas suggests, by far superior to my simple code.
Let me suggest to follow George Tokas directions and, based on this code, make it better by creating classes, by exploring the best of Builder C++.

Hope it helps.

Jose
0

Featured Post

What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

Join & Write a Comment

Update (December 2011): Since this article was published, the things have changed for good for Android native developers. The Sequoyah Project (http://www.eclipse.org/sequoyah/) automates most of the tasks discussed in this article. You can even fin…
Jaspersoft Studio is a plugin for Eclipse that lets you create reports from a datasource.  In this article, we'll go over creating a report from a default template and setting up a datasource that connects to your database.
This tutorial covers a step-by-step guide to install VisualVM launcher in eclipse.
THe viewer will learn how to use NetBeans IDE 8.0 for Windows to perform CRUD operations on a MySql database.

708 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

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now