May 14, 2024, 12:22:47 AM

News:

Own IWBasic 2.x ? -----> Get your free upgrade to 3.x now.........


Tab Control?

Started by Doc, January 31, 2006, 05:24:01 AM

Previous topic - Next topic

0 Members and 2 Guests are viewing this topic.

donh

Thanks much

Much beter examples than waht I have been looking at in several books they only gave partial examples at the explination was clear as mud.
Now what you explied the other day and this I should be able to make better progress.  I already see from your example a better way to respond to the tab than my ugly way.
But thats what one book showed.
;D

Doc

Bet you folks think this thread will never end...  ;)

Because they seem to be perfect candidates (due to a personal motivation factor), I've decided that these tab examples will serve as my "line in the sand" from an OOP learning perspective. It's gonna be now or never, so hopefully you good folks will have enough patience.

.........................

I understand that in the Window version of the tab sample, a new window named "TabDemo" is subclassed, complete with the methods necessary to work with the new class. Based on that, maybe someone can fill in the gaps for the things I know that I don'y fully understand.

Q1.
Snip-> class TabDemo : CWindow
I'm thinking that the colon designates that the new class is derived from the CWindow class, but does it actually serve as a pointer to the parent class?

Q2.
Snip->TabDemo::OnClose(),int
How exactly does the double colon function exactly? A pointer to a virtual function or method?


Q3.
cp.Create(0,0,640,480,
...
...
cp.EnableTabs(true);

In simple terms, what does the "cp" used in cp.xxxx mean? My only guess at this point, is that it represents a pointer to the new class and/or methods. Yes/No?

Patience and assistance will be much appreciated.

-Doc-

Ionic Wind Support Team

February 18, 2006, 09:52:30 AM #52 Last Edit: February 18, 2006, 10:26:07 AM by Ionic Wizard
Q1.   Your just deriving a class from CWindow.  It is not a pointer, more like a UDT definition.  Classes are based on structures (UDT).

Q2.  Again not a pointer.  It is a implimentation of the method of a class.  In otherwords a subroutine that is part of the class and not accessable unless you are using an instance of that class.

Q3. 'cp' is the variable name. 

def cp as TabDemo;

A class is a type of variable, a very advance type but just a variable nonetheless.

Class, OOP, etc all came about with the idea of encapsulation.  Objects should manage their own data and not external global variables. 

Lets say you have a UDT containing all of the members needed to represent an image. 


struct myimage
{
int width;
int height;
int bpp; //bits per pixel
pointer memory; //where the graphic is stored
}


Then a bunch of functions that might take a parameter of the UDT type 'myimage'.  Basic stuff here, you have used it in other languages.


SUB LoadImage(mi as myimage, name as string)
{
...load the file
mi.width = GetWidth(name);
...etc
}

SUB ShowImage(mi as myimage, hwnd as UINT)
{
...
}

SUB SaveImage(mi as myimage, name as string)
{
...
}



So in order to use these functions you have to first define a variable of myimage and pass it to the functions.


def image1 as myimage;
LoadImage(image1, "happy.bmp");
ShowImage(image1, win.hwnd);
SaveImage(image1, "sad.bmp");


Simple enough, you are used to using UDT's.  And what you have done above is used OOP in its simplest form.  image1 is an instance of the myimage UDT.  The problems with the above method is that the programmer has to keep track of what function works with what UDT type.  What happens when someone changes the UDT definition without changing the subroutines?  It can get chaotic.

Classes extend the idea of a UDT 'object' by coupling them with functions that work with the data in that structure.  So lets look at a partial  class representation of the above.


class myimage
{
declare LoadImage(name as string);
declare SaveImage(name as string);
declare ShowImage(HWND as UINT);
int width;
int height;
int bpp; //bits per pixel
pointer memory; //where the graphic is stored
}

myimage::LoadImage(name as string)
{
...load the file
width = GetWidth(name);
...etc
}


Now when you declare a variable of that class you don't need the external UDT to hold the data.  Instead the compiler knows those particular members are part of the class


def image1 as myimage;
image1.LoadImage("happy.bmp");
image1.ShowImage(win.hwnd);
image1.SaveImage("sad.bmp");


What is happening here is the first statement defines a variable of type 'myimage' which is a class.  Internally it is just a structure (UDT) that has all of the member variables + 1 for a table of virtual functions.  If you were to peer into memory it would just look like a structure.

myimage
{
pointer _VTABLE_
int width;
int height;
int bpp; //bits per pixel
pointer memory; //where the graphic is stored
}

And you can use a class variable just like it was a UDT in most cases.


def image1 as myimage;
image1.width = 0;


The fun part comes with the member functions.  Lets look at one of them:


image1.LoadImage("happy.bmp");


The compiler translates this into a function call that kind of looks like this:


myimage@LoadImage(&image1, "happy.bmp");


Think about it.  When you wrote the class method for LoadImage the compiler first came up with unique name so the subroutine wouldn't clash with any other names, and then did something interesting.  It added a parameter at the beginning called the 'this' pointer.


myimage::LoadImage(name as string)
{
}


Gets converted to  (in psuedo terms)


SUB myimage@LoadImage(myimage *this, name as string)
{
}


The result is a group of subroutines, and the data associated with those subroutines, in one package known simply as an "object". When your code is executing within a method of that object (a subroutine of that class) it has direct access to the variables of the object structure.  For example consider the snippet, copied from above


myimage::LoadImage(name as string)
{
...load the file
width = GetWidth(name);
...etc
}


In particular the line

width = GetWidth(name);

"width" is a member variable of the class "myimage".  When the compiler encounters a variable name that your referencing in a class method it first checks the class to see if you have a member of that name.  In this case we do so in essance the compiler is doing this:


this->width = GetWidth(name);


'this' is that added parameter the compiler adds to each class subroutine.  It is a pointer whose type is the same as the class and an address of your class variable is passed.  Putting it together with the function call:

image1.LoadImage("happy.bmp");

translates to:

myimage@LoadImage(&image1,"happy.bmp");

------------

myimage::LoadImage(name as string)

translates to

SUB myimage@LoadImage(myimage *this, name as string)

------------

and

this->width = GetWidth(name);

accesses the 'width' member of the class structure passes automatically to the LoadImage method.

Understand?
Ionic Wind Support Team

Doc

QuoteUnderstand?

Well, obviously not just yet. But I will.  :)
...I'm not gonna backoff an inch or head in any other directions until I *do* have a basic understanding. I've put it off way too long already and I've reached a point where avoiding the issue is a hindrance.

I'll print your mini-lecture and study it along with the examples until it becomes clear.

Thank you very much kind sir!

-Doc-