March 28, 2024, 04:22:17 AM

News:

IonicWind Snippit Manager 2.xx Released!  Install it on a memory stick and take it with you!  With or without IWBasic!


OOP baby steps

Started by kryton9, July 24, 2006, 01:49:33 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

kryton9

July 24, 2006, 01:49:33 AM Last Edit: July 24, 2006, 03:07:01 PM by kryton9
I wanted to share my baby steps in learning OOP programmnig, so it might help others who are in the same boat.
This website was mentioned in a few posts on these forums and as far as I can tell a great recommendation. The author
explains stuff in the shortest and clearest manner I would suppose this stuff could be explained.

http://www.cplusplus.com/doc/tutorial/classes.html

As a test I just took this short example to see if I could convert it, and finally did.

I am not commenting heavily as I really don't understand things well enough.
I am sort of if I get an error, I take things out and recompile and sort of wade my way through.
As I understand more and get feedback and see options I will start commenting.

My goal is to use that site as a guide. So users can read the theory and explanation there. Then I will try to convert all his examples
into console versions first and then their windowed versions and in some cases dialog versions.
Hopefully this will help lay out the ground work for OOP for us Newbies.

Here is the short c++ code:
// classes example
#include <iostream>
using namespace std;

class CRectangle {
ÂÃ,  ÂÃ,  int x, y;
ÂÃ,  public:
ÂÃ,  ÂÃ,  void set_values (int,int);
ÂÃ,  ÂÃ,  int area () {return (x*y);}
};

void CRectangle::set_values (int a, int b) {
ÂÃ,  x = a;
ÂÃ,  y = b;
}

int main () {
ÂÃ,  CRectangle rect;
ÂÃ,  rect.set_values (3,4);
ÂÃ,  cout << "area: " << rect.area();
ÂÃ,  return 0;
}


I hope these conversions will help others learning oop for the first time:)
My Aurora Conversion:

//CRectangle definition
class CRectangle
{
declare CRectangle();
declare _CRectangle();
declare set_values (int a,int b);
declare area (), int;
int x,y;
}

//CRectangle Implementation
CRectangle::CRectangle()
{
}

CRectangle::_CRectangle()
{
}
CRectangle::set_values(int a, int b)
{
x = a;
y = b;
}
CRectangle::area()
{
return (x*y);
}


global sub main ()
{
CRectangle rect;
rect.set_values (3,4);
print( "x: ",rect.x,"ÂÃ,  y: ",rect.y,"ÂÃ,  area: ",rect.area());
While GetKey(true) != " "; // press spacebar to exit
}


In case you are wondering, as I am... this did not work. Partial Code Block:
//CRectangle definition
class CRectangle
{
   declare CRectangle();
   declare _CRectangle();
   declare void set_values (int,int);
   declare int area (), int;
   int x,y;
}

And I don't know if this sort of thing is allowed in Aurora:
int area () {return (x*y);}

Once I get some more understanding from this example. I will take it nice and slow and gradually make those baby steps forwards and hope it helps others.

Ionic Wind Support Team

July 24, 2006, 07:40:37 AM #1 Last Edit: July 24, 2006, 07:48:29 AM by Paul Turley
declare area(),int
{
return(x * y);
}

is allowed.
Ionic Wind Support Team

kryton9

July 24, 2006, 10:14:01 AM #2 Last Edit: July 24, 2006, 11:10:40 AM by kryton9
Oooo, is there a difference in defining it where it is declared or doing it outside of the class with ::ÂÃ,  ÂÃ, ?

Ok I tried it as:
class CRectangle
{
   
   declare CRectangle();
   declare _CRectangle();
   declare set_values (int a,int b);
   declare area(),int
   {
      return(x * y);
   }
   int x,y;
}

But I get undefined variable error messages for x and y. I then tried putting the int x,y; first as the first part of the class and then get class errors.
How would I define the methods in the class itself and not outside without getting these sort of errors?

class CRectangle
{
   int x,y;
   declare CRectangle();
   declare _CRectangle();
   declare set_values (int a,int b);
   declare area(),int
   {
      return(x * y);
   }
}

kryton9

July 24, 2006, 12:41:28 PM #3 Last Edit: July 24, 2006, 12:46:27 PM by kryton9
I thought well before I get into that great site's examples. Let me do the simplest app in console and then in a window and in a dialog. This way it will be a lot easier to understand how to get started with Aurora and then move onto classes and things.

Console App:
// Console Program
// Hello World
//
global sub main( ) // all Aurora programs have a global sub main()
{
ÂÃ,  ÂÃ, print("Hello World");
ÂÃ,  ÂÃ, While GetKey() = "";// equivalent to press any key to exit
}


Windows App:

// Windows Program
// Hello World
//
// From what I can tell, this is the minimum of things required to bring up a window
// and to close it.
//
//MyWin definition
class MyWin : CWindow
{
declare MyWin();
declare _MyWin();
declare virtual OnClose(),int;
}

//MyWin Implementation
MyWin::MyWin() //This constructs the class. I think this allocates memory.
{
}

MyWin::_MyWin() //This destructs the class. I think this frees the memory.
{
}
MyWin::OnClose(),int //needed to close the window, without this clicking on the close button has no effect.
{
Destroy();
return 0;
}

global sub main( ) // all Aurora programs have a global sub main()
{
MyWin win; // in reading, it says that a class is never directly used. It is always instantiated into an object.
ÂÃ,  ÂÃ, // In this case, my class MyWin is instantiating the object win.
ÂÃ,  ÂÃ, // If you look in the Aurora's Help:Aurora Users Guide:Programmers Reference:Classes:CWindow:Methods
ÂÃ,  ÂÃ, // You will see a lot of Methods, such as Create and WriteText that are available. That is where these came from.
ÂÃ,  ÂÃ, // If you look in Aurora's Help:Aurora Users Guide:Programmers Reference:Classes:CWindow:Constants:Aurora specific window styles
ÂÃ,  ÂÃ, // You will find these AWS_ definitions.
win.Create(0,0,150,75,AWS_VISIBLE|AWS_CENTERED|AWS_MINIMIZEBOX|AWS_CAPTION|AWS_SYSMENU|AWS_AUTODRAW,0,"Test",0);
win.WriteText(25,10,"Hello World");// another CWindow Method
do
{
wait();
} until !win.IsValid(); // another CWindow Method
}


There is a wonderful Tool in Aurora to help with Classes. Paul wrote a very good Tutorial on it here:
http://www.ionicwind.com/forums/index.php?topic=673.0ÂÃ,  ÂÃ, reply #11

Now the dialog version. You can use the wonderful Dialog Editor in the Tools menu to get a lot of the code and then modify it.

// Windows Program
#define BUTTON_1 1
#define BUTTON_2 2
class dlg:CDialog
{
declare OnInitDialog(),int;
declare OnClose(),int;
declare OnControl(int nID, int nNotifyCode, unsigned int hControl),int;
}

global sub main()
{
dlg d1;
ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  // I substituted the AWS_ definitions from the Window example and pasted over the long hexadecimal number that represented these items
d1.Create(0,0,300,202,AWS_VISIBLE|AWS_CENTERED|AWS_MINIMIZEBOX|AWS_CAPTION|AWS_SYSMENU|AWS_AUTODRAW,0,"Test",0);
d1.AddControl(CTBUTTON,"OK",24,157,70,20,0x5000000B,0x0,BUTTON_1);
d1.AddControl(CTBUTTON,"Cancel",165,156,70,20,0x5000000B,0x0,BUTTON_2);
d1.AddControl(CTSTATIC,"Hello World",18,13,70,20,0x5000010B,0x0,STATIC_3);
d1.DoModal();
return 0;
}

dlg::OnClose(),int
{
CloseDialog(1);
return true;
}

dlg::OnInitDialog(),int
{
/* Initialize any controls here */
CenterWindow();
return true;
}

dlg::OnControl(int nID, int nNotifyCode, unsigned int hControl),int
{
select nID
{
case BUTTON_1:
if(nNotifyCode = 0)
{
/*button clicked*/
MessageBox(this,"OK Pressed","Info");
}
case BUTTON_2:
if(nNotifyCode = 0)
{
/*button clicked*/
CloseDialog(1); // destroy(); didn't work
}
}
return true;
}


You might ask, how do you know to declare a method virtual? I asked the same question and Paul replied with this nice answer:
The template Larry uses for the help file calls it an "overridable" method.ÂÃ,  Which is the same as a virtual method.

For example the OnCreate description says:


Quote
Event Handler Method (overrideable)


Meaning it is called in response to a window message and is a virtual method.ÂÃ, 

kryton9

Moving on... this is from this page:
http://www.cplusplus.com/doc/tutorial/classes.html
In the Constructors and destructors section.

C++ Code:
// example: class constructor
#include <iostream>
using namespace std;

class CRectangle {
ÂÃ,  ÂÃ,  int width, height;
ÂÃ,  public:
ÂÃ,  ÂÃ,  CRectangle (int,int);
ÂÃ,  ÂÃ,  int area () {return (width*height);}
};

CRectangle::CRectangle (int a, int b) {
ÂÃ,  width = a;
ÂÃ,  height = b;
}

int main () {
ÂÃ,  CRectangle rect (3,4);
ÂÃ,  CRectangle rectb (5,6);
ÂÃ,  cout << "rect area: " << rect.area() << endl;
ÂÃ,  cout << "rectb area: " << rectb.area() << endl;
ÂÃ,  return 0;
}


Aurora Conversion:
// Console Program
//CRectangle definition
class CRectangle
{
declare CRectangle(int a, int b);
declare _CRectangle();
declare area (), int;
int width,height;
}
//CRectangle Implementation
CRectangle::CRectangle(int a, int b) //the constructor replaces the set_values method from the previous example.
{
width = a;
height = b;
}
CRectangle::_CRectangle()
{
}
CRectangle::area()
{
return (width*height);
}
global sub main ()
{
CRectangle rect;// I couldn't get something like this to work: CRectangle rect (3,4); or CRectangle rect.Crectangle (3,4);
CRectangle rectb;
rect.CRectangle (3,4);
rectb.CRectangle (5,6);
print( "Width: ",rect.width,"ÂÃ,  Height: ",rect.height,"ÂÃ,  Area: ",rect.area());
print( "Widthb: ",rectb.width,"ÂÃ,  Heightb: ",rectb.height,"ÂÃ,  Areab: ",rectb.area());
While GetKey(true) != " "; // press spacebar to exit
}

kryton9

Here is the next example which is the last one in the constructors and destructors section at:ÂÃ,  http://www.cplusplus.com/doc/tutorial/classes.html

c++ code:
// example on constructors and destructors
#include <iostream>
using namespace std;

class CRectangle {
ÂÃ,  ÂÃ,  int *width, *height;
ÂÃ,  public:
ÂÃ,  ÂÃ,  CRectangle (int,int);
ÂÃ,  ÂÃ,  ~CRectangle ();
ÂÃ,  ÂÃ,  int area () {return (*width * *height);}
};

CRectangle::CRectangle (int a, int b) {
ÂÃ,  width = new int;
ÂÃ,  height = new int;
ÂÃ,  *width = a;
ÂÃ,  *height = b;
}

CRectangle::~CRectangle () {
ÂÃ,  delete width;
ÂÃ,  delete height;
}

int main () {
ÂÃ,  CRectangle rect (3,4), rectb (5,6);
ÂÃ,  cout << "rect area: " << rect.area() << endl;
ÂÃ,  cout << "rectb area: " << rectb.area() << endl;
ÂÃ,  return 0;
}


Aurora Conversion:
// Console Program
//CRectangle definition
class CRectangle
{
declare CRectangle(int a, int b);
declare _CRectangle();
declare area (), int;
int *width,*height;
}
//CRectangle Implementation
CRectangle::CRectangle(int a, int b) //the constructor replaces the set_values method from the previous example.
{
width = new(int,a);ÂÃ,  // I just kept trying every possible way to get it to work and got this working.
height = new(int,b); // as a conversion.
/* this also works
width = new(int, 1);
height = new(int, 1);
*width=a;
*height=b;
if you read the pointer section at the site (http://www.cplusplus.com/doc/tutorial/pointers.html)
great way to remember and view pointers is as:
Notice the difference between the reference and dereference operators:
& is the reference operator and can be read as "address of"
* is the dereference operator and can be read as "value pointed by"
Thus, they have complementary (or opposite) meanings. A variable referenced with & can be dereferenced with *.
*/
}
CRectangle::_CRectangle()
{
delete width;
delete height;
}
CRectangle::area()
{
return (*width * *height);
}
global sub main ()
{
CRectangle rect;// I couldn't get something like this to work: CRectangle rect (3,4); or CRectangle rect.Crectangle (3,4);
CRectangle rectb;
rect.CRectangle (3,4);
rectb.CRectangle (5,6);
print( "Width: ",rect.width,"ÂÃ,  Height: ",rect.height,"ÂÃ,  Area: ",rect.area());
print( "Widthb: ",rectb.width,"ÂÃ,  Heightb: ",rectb.height,"ÂÃ,  Areab: ",rectb.area());
While GetKey(true) != " "; // press spacebar to exit
}

kryton9

Before I move on, I want to learn how to declare and define the method in one step within the class itself instead of outside of the class using ::

Ionic Wind Support Team

I think we already covered that.


class CRectangle
{
   int x,y;
   declare CRectangle()
   {
   x = 0; y=0;
   }
   declare set_values (int a,int b);
   declare area(),int
   {
      return(x * y);
   }
}

CRectangle::set_values(int a,int b)
{
x=a;
y=b;
}

global sub main()
{
CRectangle rc;
rc.set_values(2,4);
print(rc.Area());
while getkey() = "";
}


Ionic Wind Support Team

kryton9

July 24, 2006, 03:54:22 PM #8 Last Edit: July 24, 2006, 03:56:20 PM by kryton9
I had replied that I was getting errors from what I had written. Looking at this example I see it was having the ; at the end of the declaration and definition within the class.

Here is the same code where everthing is within the class. I just prefer it that way. They talk about encapsulation, and I just figure it should be in one class section and not those outside
definitions. Just personal taste I guess and I think a way I can warm up to this new stuff. As long as there is nothing wrong with doing it that way?

class CRectangle
{
ÂÃ,  ÂÃ, int x,y;
ÂÃ,  ÂÃ, declare CRectangle()
ÂÃ,  ÂÃ, {
ÂÃ,  ÂÃ, x = 0; y=0;
ÂÃ,  ÂÃ, }
ÂÃ,  ÂÃ, declare set_values (int a,int b)
{
x=a; y=b;
}
ÂÃ,  ÂÃ, declare area(),int
ÂÃ,  ÂÃ, {
ÂÃ,  ÂÃ,  ÂÃ,  return(x * y);
ÂÃ,  ÂÃ, }
}

global sub main()
{
CRectangle rc;
rc.set_values(2,4);
print(rc.Area());
while getkey() = "";
}


Can you instantiate and also send parameters at the same time?ÂÃ,  As below:
class CRectangle
{
ÂÃ,  ÂÃ, int x,y;
ÂÃ,  ÂÃ, declare CRectangle(int a, int b)
ÂÃ,  ÂÃ, {
ÂÃ,  x=a; y=b;
ÂÃ,  ÂÃ, }
ÂÃ,  ÂÃ, declare area(),int
ÂÃ,  ÂÃ, {
ÂÃ,  ÂÃ,  ÂÃ,  return(x * y);
ÂÃ,  ÂÃ, }
}

global sub main()
{
CRectangle rc (2,4);
print(rc.Area());
while getkey() = "";
}


Or:
class CRectangle
{
ÂÃ,  ÂÃ, int x,y;
ÂÃ,  ÂÃ, declare CRectangle(int a, int b)
ÂÃ,  ÂÃ, {
ÂÃ,  x=a; y=b;
ÂÃ,  ÂÃ, }
ÂÃ,  ÂÃ, declare area(),int
ÂÃ,  ÂÃ, {
ÂÃ,  ÂÃ,  ÂÃ,  return(x * y);
ÂÃ,  ÂÃ, }
}

global sub main()
{
CRectangle rc.CRectangle (2,4);
print(rc.Area());
while getkey() = "";
}


Thanks. I get errors trying it both ways.

Ionic Wind Support Team

Nope.  Constructors can't have parameters as of yet.

And it is ok to have accessor functions within the class, like Area(), but for larger functions you'll want to keep the class definition and implementation separate. 

If everything is in one source file then it makes no difference either way.  But when you get more advanced you'll want to have your definitions in an include file, use projects, and be able to use that class in other source files. 

It will still work with everything in the class definition of course.  But it makes more work for the linker since every time you include that file that has a method defined in the class your going to generate a duplicate code block.  And the linker has to merge them into a single reference. Which takes more time.

For a small project say < 10 source files I wouldn't worry too much.  Something as large as an IDE, with hundreds of source files, it can add a lot of time to the build.

Paul.
Ionic Wind Support Team

kryton9

July 24, 2006, 04:28:23 PM #10 Last Edit: July 24, 2006, 04:30:07 PM by kryton9
Thanks Paul, that I actually understood :)

Since there are so many tutorials on c++ and example code.
Would you want me to make an html table or works spreadsheet or sql database like:
C++ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ, Aurora Current VersionÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ, Aurora Planned
Constructors with parametersÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  NoÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ,  ÂÃ, Yes
...

Since I am new to all of this, I will compile a list as best as I can and thenÂÃ,  you can edit it and this way all of this sort of stuff will be in one place
and it will save you time to not have to answer so many newbie questions. And give you more time to develop and write cool code samples.

Let me know if that is ok and which you would prefer.

Ionic Wind Support Team

Most of the answers you seek have already been answered a few times here ;).  Search for them, once you know the terminology.
Ionic Wind Support Team

kryton9

July 24, 2006, 04:33:16 PM #12 Last Edit: July 24, 2006, 06:45:08 PM by kryton9
They are all over the place, I thought it would help everyone to have it in one place where the info is current.

OK, I decided to go ahead and start this project as I know it will benfit me and I am sure others. Here is the thread where the updated file will be.
http://www.ionicwind.com/forums/index.php?topic=758.new#new

Steven Picard

Quote from: Paul Turley on July 24, 2006, 04:01:32 PM
Nope.ÂÃ,  Constructors can't have parameters as of yet.
So, this is something we can eventually look forward too?  ;D

Kale

Quote from: stevenp on July 25, 2006, 08:08:30 AM
Quote from: Paul Turley on July 24, 2006, 04:01:32 PM
Nope.ÂÃ,  Constructors can't have parameters as of yet.
So, this is something we can eventually look forward too?ÂÃ,  ;D

Can classes accept parameters?

Something like this:


class MyWin(param1, param2, etc) : CWindow
{
ÂÃ,  ÂÃ,  int m_one;
    int M-two;
    declare MyWin()
    {
        m_one = param1;
        m_two = param2;
    }
    ...
}

MyWin Window(100, 200, etc..)



Ionic Wind Support Team

No.  As stated class constuctors don't accept parameters.
Ionic Wind Support Team

kryton9

July 31, 2006, 01:16:40 PM #16 Last Edit: July 31, 2006, 02:32:32 PM by kryton9
Ok, I think these next few steps will really clear things up for those of us who are lost and don't understand the other's help as they get it, but forgot that it is mumbo jumbo to the rest of us.
This code will be the foundation for the next steps that will cover most of what is really confusing to us.

If you looked through the earlier examples, then this is a simpler version of those, but it does show one new aspect that is you can use a class to define another object and start doing cool things. That is with one class you can create as many objects as you want. This is a simple example showing how to create two windows. As I said, it will be the foundation for the next few steps that will show the more complicated things as I figure them out.

I wanted to keep the code as short as possible, show something useful and then you can easily see as we progress with the baby steps :)

// Windows Program
//MyWindow Definition
class MyWindow : CWindowÂÃ,  // MyWindow is the name of my new Class and it is derived from an existing Class CWindow
{
declare MyWindow();ÂÃ,  // This method (function that belongs to this class) is the Constructor. It is required for all classes
declare _MyWindow(); // This method is the Destructor. It is required for all classes
declare virtual OnClose(),int; //This is a method we are defining and up to your needs
// to keep this simple. I did not add any variables that belong to this class. That will come later.
}

//MyWindow Implementation
MyWindow::MyWindow()ÂÃ,  // This is the constructor implementation
{
}

MyWindow::_MyWindow() // This is the destructor, again both of these are required for all classes.
{
}

MyWindow::OnClose(),int // This is our method to close. Without this here and in the definition above, we could not close the windows
{
Destroy();
return 0;
}

global sub main()
{
MyWindow win1; // our first object based on our class MyWindow. We named it win1
MyWindow win2; // our second object from the same class
win1.Create(0,0,200,120,AWS_VISIBLE|AWS_MINIMIZEBOX|AWS_CAPTION|AWS_SYSMENU|AWS_AUTODRAW,0,"Window One",0);
win1.WriteText(30,35,"Hello World.");
win2.Create(200,0,200,120,AWS_VISIBLE|AWS_MINIMIZEBOX|AWS_CAPTION|AWS_SYSMENU|AWS_AUTODRAW,0,"Window Two",0);
win2.WriteText(30,35,"How are you?");
do
{
wait();
} until !win1.IsValid();// win2 can close, but the program keeps running till win1 is closed
}

// You are probably wondering, where did WriteText() come from? Well it is a method from the base class that MyWindow was derived from.
// If you look in the aurora help you will see this method in the classes section under CWindow


Ok here is the same code without all the comments, I think it is nice to have both ways, I think once you read through the commented source, it is easier to look at and to really follow what is going on without all the comments.

// Windows Program
class MyWindow : CWindow
{
declare MyWindow();
declare _MyWindow();
declare virtual OnClose(),int;
}

//MyWindow Implementation
MyWindow::MyWindow()
{
}

MyWindow::_MyWindow()
{
}

MyWindow::OnClose(),int
{
Destroy();
return 0;
}

global sub main()
{
MyWindow win1;
MyWindow win2;
win1.Create(0,0,200,120,AWS_VISIBLE|AWS_MINIMIZEBOX|AWS_CAPTION|AWS_SYSMENU|AWS_AUTODRAW,0,"Window One",0);
win1.WriteText(30,35,"Hello World.");
win2.Create(200,0,200,120,AWS_VISIBLE|AWS_MINIMIZEBOX|AWS_CAPTION|AWS_SYSMENU|AWS_AUTODRAW,0,"Window Two",0);
win2.WriteText(30,35,"How are you?");
do
{
wait();
} until !win1.IsValid();
}

kryton9

Ok, this next example is to take the previous example(Step 6) and show you can use project files and multiple source files.

It might seem silly to do it with this short sample, but I am sure you can see how neat it will be to have your large complex classes in their own source
file once you get them working the way you want.

The main source file:
// Windows Program
class MyWindow : CWindow
{
declare MyWindow();
declare _MyWindow();
declare virtual OnClose(),int;
}

global sub main()
{
MyWindow win1;
MyWindow win2;
win1.Create(0,0,200,120,AWS_VISIBLE|AWS_MINIMIZEBOX|AWS_CAPTION|AWS_SYSMENU|AWS_AUTODRAW,0,"Window One",0);
win1.WriteText(30,35,"Hello World.");
win2.Create(200,0,200,120,AWS_VISIBLE|AWS_MINIMIZEBOX|AWS_CAPTION|AWS_SYSMENU|AWS_AUTODRAW,0,"Window Two",0);
win2.WriteText(30,35,"How are you?");
do
{
wait();
} until !win1.IsValid();
}


The second source file, the class(es):
class MyWindow : CWindow
{
declare MyWindow();
declare _MyWindow();
declare virtual OnClose(),int;
}
//MyWindow Implementation
MyWindow::MyWindow()
{
}

MyWindow::_MyWindow()
{
}

MyWindow::OnClose(),int
{
Destroy();
return 0;
}


As you can see, the defintion is in both files, but implementation is in the second source file. Like I said, with long and complex classes, it will be very useful.

I will just number the steps to do:

1. Make sure that Aurora is open and that no files are open or projects.

2. Now go to the menubar select File: New: Project
3. Project Name: k9 - 7 oop baby steps
ÂÃ,  ÂÃ,  Project Path: Where you want to save the project and files
ÂÃ,  ÂÃ,  Project Type: Windows Executeable
ÂÃ,  ÂÃ,  Output File: It will automatically generate a name based on your Project Name
ÂÃ,  ÂÃ,  Press the OK button

4. Now copy the first source file and paste it into a new source file within the open project
ÂÃ,  ÂÃ,  we just created.
5. Go to File: Save As:
6. File Name:ÂÃ,  k9 - 7 oop baby steps a main.src
7. Now go to the menubar select Project: Insert File into Project

8. Now copy the second source file and paste it into a new source file within the open project
ÂÃ,  ÂÃ,  we just created.
5. Go to File: Save As:
6. File Name:ÂÃ,  k9 - 7 oop baby steps b classes.src
7. Now go to the menubar select Project: Insert File into Project

8. Now go to the menubar select View:
ÂÃ,  ÂÃ,  Make sure Project Workspace has a check next to it, if not select it.
ÂÃ,  ÂÃ,  Now if you look in the bottom right hand of your Aurora Window you will see the 2 source files listed.

9. Now go to the menubar select File: Save All
10. Now go to the menubar select File: Close Project
11. Close the open source files also.

Steps 9 through 11 are not necessary, but I wanted to show how you have a project file and how to work with it.

So now you should have a blank Aurora screen, with nothing open and the project closed.

1. Now go to the menubar select File: Open Project
2. Select : k9 - 7 oop baby steps.awp
3. Click Open

As you see, you opened a project, but you still got a blank screen.
Ok now just look in the Project Workspace Pane

You will see your two source files in there.

Just double-click the source files listed in the Project Workspace Pane and they will open up.
You could of course go through File and open them that way too.

Ok, now just click the exe icon in the toolbar and you will get a Build Completed message in the Output Window, which is usually to the left of the Project Workspace.

Now go to the folder where you the exe was saved, which is where your project file is and you can run it.




kryton9

This is a continuation of steps 6 and 7.

You might at this point be wondering, why do all of this?

On a short example, the benefit isn't seen, but it needs to be short so that we can understand what is happening without being lost in the code :)

But imagine you had ten classes and they were pretty long in code.
So it would be nice if each one could be in its own source file.

But if you had ten source files and you still had to put the definitions into your main source file, it sort of adds lots of lines of code to your main source file, that you might not want.

That is where the include file comes in. You would put all your class definitions into the include file. Your class implementation in their own source file, or one long one up to you, and you would have your main source file.

One very important thing to note:
Only Source Files can be inserted into projects. Include files should not be inserted. The include file should be in the same folder as your source files.

I will assume you went through at least the last 2 examples and make the steps shorter based on that.

Main Source File Code:
// Windows Program
#include "k9 - 7 oop baby steps.inc"

global sub main()
{
MyWindow win1;
MyWindow win2;
win1.Create(0,0,200,120,AWS_VISIBLE|AWS_MINIMIZEBOX|AWS_CAPTION|AWS_SYSMENU|AWS_AUTODRAW,0,"Window One",0);
win1.WriteText(30,35,"Hello World.");
win2.Create(200,0,200,120,AWS_VISIBLE|AWS_MINIMIZEBOX|AWS_CAPTION|AWS_SYSMENU|AWS_AUTODRAW,0,"Window Two",0);
win2.WriteText(30,35,"How are you?");
do
{
wait();
} until !win1.IsValid();
}


As you see the MyWindow Class definition has been moved to the include file. We just use the line:
#include "k9 - 7 oop baby steps.inc"
The name in quotes is what we are naming the include file we will create.

The include file code:
//MyWindow definition
class MyWindow : CWindow
{
declare MyWindow();
declare _MyWindow();
declare virtual OnClose(),int;
}


The Second Source File Class Code:
class MyWindow : CWindow
{
declare MyWindow();
declare _MyWindow();
declare virtual OnClose(),int;
}
//MyWindow Implementation
MyWindow::MyWindow()
{
}

MyWindow::_MyWindow()
{
}

MyWindow::OnClose(),int
{
Destroy();
return 0;
}


Again, only your source files should be inserted into your project. The inlcude file is in the same folder as your source and project file. Just build and run the executeable.
You now get an idea of how the code can be broken down into manageable chunks.


kryton9

Step 9 is the same example as in step 6. But I used pointers for one of the windows (win2)so you can see how it works.

// Windows Program
class MyWindow : CWindow
{
declare MyWindow();
declare _MyWindow();
declare virtual OnClose(),int;
}

//MyWindow Implementation
MyWindow::MyWindow()
{
}

MyWindow::_MyWindow()
{
}

MyWindow::OnClose(),int
{
Destroy();
return 0;
}

global sub main()
{
MyWindow win1;
MyWindow *win2 = new(MyWindow,1);
win1.Create(0,0,200,120,AWS_VISIBLE|AWS_MINIMIZEBOX|AWS_CAPTION|AWS_SYSMENU|AWS_AUTODRAW,0,"Window One",0);
win1.WriteText(30,35,"Hello World.");
win2->Create(200,0,200,120,AWS_VISIBLE|AWS_MINIMIZEBOX|AWS_CAPTION|AWS_SYSMENU|AWS_AUTODRAW,0,"Window Two",0);
win2->WriteText(30,35,"How are you?");
do
{
wait();
} until !win1.IsValid();
delete win2;
}


MyWindow *win2 = new(MyWindow,1);
This basically says I am making a new object win2 from the class MyWindow. The * indicates that it is a pointer.
new(MyWindow, 1); is setting aside memory of the size requred for the class MyWindow

Whenever you use a new you also have to have a delete or when your program terminates that memory will not be returned to the operating system.
You can compare win1 and win2 and see how the member methods (functions) are accessed either with pointers or without.

Step 8 would be exactly as it is, that is the the include file and the second source file would remain the same only your main source file would change to:
// Windows Program
#include "k9 - 7 oop baby steps.inc"

global sub main()
{
MyWindow win1;
MyWindow *win2 = new(MyWindow,1);
win1.Create(0,0,200,120,AWS_VISIBLE|AWS_MINIMIZEBOX|AWS_CAPTION|AWS_SYSMENU|AWS_AUTODRAW,0,"Window One",0);
win1.WriteText(30,35,"Hello World.");
win2->Create(200,0,200,120,AWS_VISIBLE|AWS_MINIMIZEBOX|AWS_CAPTION|AWS_SYSMENU|AWS_AUTODRAW,0,"Window Two",0);
win2->WriteText(30,35,"How are you?");
do
{
wait();
} until !win1.IsValid();
delete win2;
}

kryton9

This is just to show that stuff can be written in a style to fit your needs.

For example This is the original snippet:
// Windows Program
class MyWindow : CWindow
{
declare MyWindow();
declare _MyWindow();
declare virtual OnClose(),int;
}

//MyWindow Implementation
MyWindow::MyWindow()
{
}

MyWindow::_MyWindow()
{
}

MyWindow::OnClose(),int
{
Destroy();
return 0;
}


If you thought, man I am wasting lots of lines on lots of minimal code and have to keep scrolling.
You can always write it as:
class MyWindow : CWindow
{declare MyWindow();declare _MyWindow();declare virtual OnClose(),int; }

//MyWindow Implementation
MyWindow::MyWindow(){}
MyWindow::_MyWindow(){}

MyWindow::OnClose(),int
{Destroy();return 0;}


Or even tighter:
// Windows Program
class MyWindow : CWindow{declare MyWindow();declare _MyWindow();declare virtual OnClose(),int;}

//MyWindow Implementation
MyWindow::MyWindow(){}MyWindow::_MyWindow(){}MyWindow::OnClose(),int{Destroy();return 0;}


That is where having the ; at the end of the lines and the braces help giving that flexibility, although it is a lot harder to read,
just wanted to take a break and verify that it could be done that way.

kryton9

This will just build on the previous examples. So hope you read through them before going on with this one.

Here we will add a function outside of our main source and be able to call it.
Took awhile for me to get this working, just trial and error trying all sorts of combos and voila it works. Hope it helps.

The Main Source File:
// Windows Program
#include "k9 - 10 oop baby steps.inc"

global sub main()
{
MyWindow win1;
MyWindow win2;
win1.Create(0,0,200,120,AWS_VISIBLE|AWS_MINIMIZEBOX|AWS_CAPTION|AWS_SYSMENU|AWS_AUTODRAW,0,"Window One",0);
win1.WriteText(30,35,"Hello World.");
win2.Create(200,0,300,120,AWS_VISIBLE|AWS_MINIMIZEBOX|AWS_CAPTION|AWS_SYSMENU|AWS_AUTODRAW,0,"Window Two",0);
win2.WriteText(30,35,Help());
do
{
wait();
} until !win1.IsValid();
}

We just made this change to the original: win2.WriteText(30,35,Help());
Basically calling our Help() function instead of putting a string there directly.

Our classes source, this is unchanged:
// additional classes

class MyWindow : CWindow
{
declare MyWindow();
declare _MyWindow();
declare virtual OnClose(),int;
}
//MyWindow Implementation
MyWindow::MyWindow()
{
}

MyWindow::_MyWindow()
{
}

MyWindow::OnClose(),int
{
Destroy();
return 0;
}


The new source file, this will be need to be added to your project. We will be returning a string.
// additional function implementations

global sub Help(), string
{
return "This is the returned string.";
}


And finally our include file, which should not be added to the project but in the same folder with the other files:
// the include files

// class definitions
class MyWindow : CWindow
{
declare MyWindow();
declare _MyWindow();
declare virtual OnClose(),int;
}

// function definitions
declare extern Help(), string;

We just added the line:
declare extern Help(), string;
 

kryton9

OK, now I need help :)

This seems like it should work. But I get one error saying unknown class, so really confused now. Thought I had all of this figured out finally :(

I want to see the solution to match this file structure as trying to understand it all, so please anyone offering help, just show what changes are needed to make it work. Thanks.

Main source:
// Windows Program
#include "k9 - 11 oop baby steps.inc"

global sub main()
{
MyWindow win1;
MyWindow *win2 = new(MyWindow,1);
win1.Create(0,0,200,120,AWS_VISIBLE|AWS_MINIMIZEBOX|AWS_CAPTION|AWS_SYSMENU|AWS_AUTODRAW,0,"Window One",0);
win1.WriteText(30,35,"Hello World.");
win2->Create(200,0,300,120,AWS_VISIBLE|AWS_MINIMIZEBOX|AWS_CAPTION|AWS_SYSMENU|AWS_AUTODRAW,0,"Window Two",0);
Help(win2);
do
{
wait();
} until !win1.IsValid();
delete win2;
}


Classes Source:
// additional classes

class MyWindow : CWindow
{
declare MyWindow();
declare _MyWindow();
declare virtual OnClose(),int;
}
//MyWindow Implementation
MyWindow::MyWindow()
{
}

MyWindow::_MyWindow()
{
}

MyWindow::OnClose(),int
{
Destroy();
return 0;
}


The functions source:
// additional function implementations

global sub Help(int *pwin2)
{
pwin2->WriteText(30,35,"Pointer to Class Test"); // this is where I get the error unknown class
}


The include file:
// the include files

// class definitions
class MyWindow : CWindow
{
declare MyWindow();
declare _MyWindow();
declare virtual OnClose(),int;
}

//function definitions
declare extern Help(int *pwin2);



Ionic Wind Support Team

The class definition only needs to be in the include file.  Then include it in "classes source".

Ionic Wind Support Team

kryton9

July 31, 2006, 08:05:41 PM #24 Last Edit: July 31, 2006, 08:08:25 PM by kryton9
Can you show me what you mean, as I had tried various combos of stuff like what you said and always got errors.

I tried what you said again and I get the same error.

#include "k9 - 11 oop baby steps.inc"

I replaced the definition in the classes sourse with the line above. And still got the same error.

I then added the line above to my functions source and got the same error.