ENDCLASS

ENDCLASS

End the declaration of a class.

Syntax

      ENDCLASS

Arguments

(This statement has no arguments)

Description

ENDCLASS marks the end of a class declaration. It is usually followed by the class methods that are not INLINE.

Examples

      CREATE CLASS TWindow
         VAR hWnd, nOldProc
      ENDCLASS

Compliance

Harbour

Platforms

All

Seealso

Object Oriented Programming, CLASS, METHOD, DATA

CLASS VAR

CLASS VAR

Define a CLASS VAR variable for a class (NOT for an Object!)

Syntax

      CLASS VAR <DataName1> [, <DataNameN>] [ AS <type> ] [ INIT <uValue> ]

Arguments

<DataName1> Name of the VAR

<type> Optional data type specification from the following:

Character, Numeric, Date, Logical, Codeblock, Nil

<uValue> Optional initial value at program startup

Description

CLASS VAR variables can also be thought of as the “properties” of an entire class. Each CLASS VAR exists only once, no matter how many objects are created. A common usage is for a counter that is incremented whenever an object is created and decremented when one is destroyed, thus monitoring the number of objects in existence for this class.

You can use the “AS <type>” clause to enforce that the CLASS VAR is maintained as a certain type. Otherwise it will take on the type of whatever value is first assigned to it.

Use the “INIT <uValue>” clause to initialize that VAR to <uValue> whenever the class is first used.

Examples

      CREATE CLASS TWindow
         VAR   hWnd,  nOldProc
         CLASS VAR lRegistered AS LOGICAL
      ENDCLASS

Compliance

Harbour

Platforms

All

Seealso

Object Oriented Programming, CLASS, METHOD, VAR

CLASS

 

CLASS

 

Define a Class for Object Oriented Programming

Syntax

      [CREATE] CLASS <ClassName> [ <FROM, INHERIT> <SuperClass1> [,<SuperClassN>] ]  [STATIC]

Arguments

<ClassName> Name of the class to define. By tradition, Harbour classes start with “T” to avoid collisions with user- created classes.

<SuperClass1…n> The Parent class(es) to use for inheritance. Harbour supports Multiple Inheritance.

STATIC This clause causes the class function to be declared as a static function. It will therefore not be available outside the current module.

Description

CLASS creates a class from which you can create objects. The CLASS command begins the class specification, in which the DATA elements (also known as instance variables) and METHODS of the class are named. The following scoping commands may also appear. They control the default scope of DATA and METHOD commands that follow them.

         EXPORTED:
         VISIBLE:
         HIDDEN:
         PROTECTED:

    The class specification ends with the END CLASS command.

Classes can inherit from multiple <SuperClasses>, and the chain of inheritance can extend to many levels.

A program uses a Class by calling the Class Constructor, usually the New() method, to create an object. That object is usually assigned to a variable, which is used to access the DATA elements and methods.

Harbour’s OOP syntax and implementation supports Scoping (Protect, Hidden and Readonly) and Delegating, and is largely compatible with Class(y)(tm), TopClass(tm) and Visual Objects(tm).

Examples

      CREATE CLASS TBColumn

         VAR Block      // Code block to retrieve data for the column
         VAR Cargo      // User-definable variable
         VAR ColorBlock // Code block that determines color of data items
         VAR ColSep     // Column separator character
         VAR DefColor   // Array of numeric indexes into the color table
         VAR Footing    // Column footing
         VAR FootSep    // Footing separator character
         VAR Heading    // Column heading
         VAR HeadSep    // Heading separator character
         VAR Width      // Column display width
         VAR ColPos     // Temporary column position on screen

         METHOD New()    // Constructor

      ENDCLASS

Compliance

Harbour

Platforms

All

Seealso

HBClass(), Object Oriented Programming, DATA, METHOD

TBrowse & TBColumn basics

TBrowse and TBColumn basics (.pdf)

Working version of sample program in this article.

 

TBr_Bass

The Art Of Simplicity

A discussion of how to create objects with Clipper using arrays, and ordinary Clipper syntax. Has several good examples.

An Introduction into Object Oriented Programming.

To me, the challenge of programming is in finding a simple clean way to implement a program. Making sure no matter how complex the specs are, the code itself stays small, strait forward, and easy to maintain.

To illustrate how to reduce the complexity of things, lets examine the box drawing routines. Normally to display a nondestructive box on the screen you write something like this:

 old_row:=row()
 old_col:=col()
 old_cursor:=setcursor()
 old_screen:=savescreen(10, 20, 16, 59)
 old_color:=setcolor("w+/n, w+/r")
 @ 10, 20, 16, 59 BOX 'ÚÄ¿³ÙÄÀ³ '

Then when you are done and wish to remove the box, you reverse the procedure:

 restscreen(10,20,16,59,old_screen)
 setcolor(old_color)
 setcursor(old_cursor)
 setpos(old_row,old_col)

This scheme results in using 9 lines of code, 5 memory variables, and requires that the programmer maintain the box coordinates in 3 different places. After going through this procedure a few times I started wondering if there was a better way of doing this.

When I tried to solve this problem, I had several false starts. I created a procedure to display the box that saved all the variables to statics, and the next time it was called it would restore the box. That didn’t work too well since I often wanted more than a single box on the screen.

Then I tried saving the memvars to an array that I used like a stack. But that didn’t work out too well either, since it required that all boxes be removed in the same order that they were created.

Then I decided that all the memvars being used to store the box information belonged in the calling routine, where they had been all along. Despite the fact that this seemed to bring me back to square one I continued with this train of thought.

If I stored all the memvars being used by the box routine in an array, then all the memvars could be stored in a single package, and passed to the calling routine without complications:

aBox := CreateBox(10, 20, 16, 59, "w+/n, w+/r")

And when I no longer needed the box and wished to restore the original screen:

DestroyBox( aBox )

Please compile DEMO1, to see the basic box functions.

CreateBox() and DestroyBox() are used to replace 10 lines of code, and the array aBox was used to replace 5 variables. Putting all the data into the array aBox and handling only the array, makes things much simpler.

Now that we have developed this technique, we could theoretically create a number functions that work together, like CreateBox() and DestroyBox(), and use the data contained in aBox. And in the file BOX.PRG, I have a group of sample functions that do just that:

 CreateBox()
 DestroyBox()
 BoldBox()
 MoveBox()

Another benefit of this technique, is that we can have multiple arrays that each correspond to separate boxes, and use them all at the same time.

For example, we could write a program with a couple of boxes:

 aBox1 := CreateBox( 05,  26,  20,  53,  "w+/n, w+/n" )
 aBox2 := CreateBox( 10,  20,  16,  59,  "w+/b, w+/b" )

To move the second box:

MoveBox( aBox2,  -08,  -18 )

Then we could give the second box a highlight:

BoldBox( aBox2, "w+/b, w+/b" )

Then to remove both boxes:

 DestroyBox(aBox2)
 DestroyBox(aBox1)

This example does some fairly complex things, and it does so, in only six lines of code. To run this example, compile the file DEMO2.PRG.

This programming technique has a name, it is called Object Oriented Programing (OOP).

According to OOP terminology the arrays aBox1 and aBox2 are objects, and the functions CreateBox, MoveBox, BoldBox, and DestroyBox are methods.

Objects are collections of related data, or in dBase terminology, arrays of related memvars. In our example, aBox1 and aBox2 are qualify as objects since they contain related data (the coordinates of the box, the original color, cursor position, cursor status, etc.).

In object oriented programming, several instances of an object can be created, and later destroyed when we are finished with them. In our example, aBox1 and aBox2, constitute two separate instances of box objects.

If you look at the example in DEMO3.PRG, you will see that the program creates an array of four box objects, and four separate instances of the box object are on the screen at once.

A methods is a special type of function. Methods are functions that are grouped together, and manipulate the same data objects. In the file BOX.PRG, you will see the code for four methods that use the box objects ( CreateBox, DestroyBox, BoldBox, MoveBox )

CreateBox is a special type of method called a constructor, because it creates a box object and initializes it.

DestroyBox is a special type of method called a destructor, because it destroys a box object and frees of the memory that the box object used.

Every time we call a method / function, we pass it the object we want the method to manipulate. In our example, we have two objects, aBox1 and aBox2. To move the first box, we called the method MoveBox() like this:

MoveBox( aBox1, 1, 1 )

And to bold the second box, we called the method BoldBox() like this:

BoldBox( aBox2, "w+/b,w+/n" )

The constructor CreateBox doesn’t need to be passed the object, because the constructor creates the object.

Now that you understand what an object is, you can create additional functions / methods that use the box object. And hopefully go on to create your own objects and methods.

Cynthia Allingham, 1991

/***
*
* BOX.PRG
*
* Written By: Cynthia Allingham 11/01/91
* Purpose: Displays exploding box on the screen
* Returns: Previous screen contents
*/
FUNC CreateBox (nTop, nLeft, nBottom, nRight, box_color)
local save_window:=savescreen(nTop, nLeft, nBottom, nRight)
local save_color:=setcolor(box_color)
local save_cursor:=setcursor()
local save_row:=row()
local save_column:=col()
@ nTop,nLeft,nBottom,nRight BOX 'ÚÄ¿³ÙÄÀ³ '
RETURN {nTop, nLeft, nBottom, nRight, save_window,;
 save_color, save_cursor, save_row, save_column}
/***
* Written By: Cynthia Allingham 11/01/91
* Purpose: destroys the box and restores old settings
*/
FUNC DestroyBox (aList)
restscreen(aList[1],aList[2],aList[3],aList[4],aList[5])
setcolor(aList[6])
setcursor(aList[7])
setpos(aList[8],aList[9])
aList:=nil
return nil
/***
* Written By: Cynthia Allingham 11/01/91
* Purpose: Changes the box border
*/
FUNC BoldBox (aList, cColor)
@ aList[1],aList[2],aList[3],aList[4];
 BOX 'ÛßÛÛÛÜÛÛ' color cColor
return nil
/***
* Written By: Cynthia Allingham 11/01/91
* Purpose: Redimensions the screen
*/
FUNC MoveBox (aList, nVert, nHorz)
local save_window:=savescreen(aList[1],aList[2],aList[3],aList[4])
dispbegin()
restscreen(aList[1],aList[2],aList[3],aList[4],aList[5])
aList[3] += nVert; aList[1]+=nVert
aList[4] += nHorz; aList[2]+=nHorz
aList[5]:=savescreen(aList[1],aList[2],aList[3],aList[4])
restscreen(aList[1],aList[2],aList[3],aList[4],save_window)
dispend()
return nil
* EOF BOX.PRG
/***
*
* DEMO1.PRG
*
* Written By: Cynthia Allingham 11/01/91
* Purpose: Simple program demonstrating the creation and
* destruction of a box object.
*/
local aBox
set procedure to box
@ 00,00,24,79 box 'ÚÄ¿³ÙÄÀ³°'
aBox:=CreateBox(10, 20, 16, 59, "w+/n, w+/r")
@22,19 say padc("Press any key to destroy the box",40)
inkey(10)
DestroyBox(aBox)
* EOF DEMO1.PRG
/***
*
* DEMO2.PRG
*
* Written By: Cynthia Allingham 11/01/91
* Purpose: Demonstates the use of two box objects
*/
local aBox1, aBox2
set procedure to box
@ 00,00,24,79 box 'ÚÄ¿³ÙÄÀ³°'
aBox1:=CreateBox(05, 26, 20, 53, "w+/n, w+/n")
message("Press any key to create a second box")
aBox2:=CreateBox(10, 20, 16, 59, "w+/b, w+/b")
message("Press any key to move the second box")
MoveBox(aBox2, -08, -18)
message ("Press any key to bold the second box")
BoldBox(aBox2, "w+/b, w+/b")
message("Press any key to destroy both boxes")
DestroyBox(aBox2)
DestroyBox(aBox1)
func message(ctext)
@22,19 say padc(ctext,40)
inkey(10)
* EOF DEMO2.PRG
/***
*
* DEMO3.PRG
*
* Written By: Cynthia Allingham 11/01/91
* Purpose: Demonstates the use of four box objects
*/
local aBox[4]
local cnt
set procedure to box
@ 00,00,24,79 box 'ÚÄ¿³ÙÄÀ³°'
aBox[1]:=CreateBox(05, 05, 09, 30, "w+/n, w+/n")
@ 06, 07 say "box #1"
aBox[2]:=CreateBox(18, 03, 22, 14, "w+/b, w+/b")
@ 20, 05 say "box #2"
aBox[3]:=CreateBox(20, 48, 22, 77, "w+/r, w+/r")
@ 21, 50 say "box #3"
aBox[4]:=CreateBox(02, 64, 12, 75, "w+/gr, w+/gr")
@ 03, 66 say "box #4"
for cnt:=1 to 12
 inkey(0.5)
 MoveBox(aBox[1], +1, 0)
 MoveBox(aBox[2], 0,+4)
 MoveBox(aBox[3], -1, 0)
 MoveBox(aBox[4], 0,-4)
next
inkey(10)
for cnt:=1 to 4
 DestroyBox(aBox[cnt])
next
* EOF DEMO3.PRG

Five years: A Brief History.

In February 2002 I’ve published the first MiniGUI version.

At that moment, only an experiment whose target for me was research about Harbour-C interface.

A lot of people were interested in the Project and from the beginning collaborated with me in many ways.

Some months later I’ve noticed that the experiment could turn in something more serious.

Being one of my basic targets the easy of use (according xBase spirit) a little time later I’ve added the ‘semi-oop’ interface. That turned the combination of Harbour+MiniGUI in a tool that besides a xBase compiler, offered a GUI, as easy to use as the VB one (yet simpler). This made grow even more the MiniGUI popularity and with it, the problems.

Some people, began an aggressive campaign of lies, pointing not only technical aspects of Harbour and MiniGUI, but personal issues, targeted to create false conflicts in the discussion groups. I let to the readers criteria the theories about the motivations of that people.

This growing brings other problems too. The most serious were the discrepancies about technical issues related with the project direction. Some contributors were not coinciding with my vision of that.

I must accept that could had been solutions for these problems, joining efforts in favor an unique target, but sadly, I don’t knew how to find solution in time.

Today there are two alternative MiniGUI versions besides mine. Yet I’ve wished to find a solution for the differences to make this not happened, that means that the seeding done five years ago, had got results, even much more ahead of my own expectations.

MiniGUI had never existed without its users and contributors and is to them (as every year) my endless gratitude.

Specially to those that got to me the initial impulse, as Grigory Filatov, Jacek Kubica, Ciro Vargas Clemov, Ryszard Rylko (who allow to me to include the HbPrinter code in MiniGUI) and Janusz Pora (I’ve had serious discrepancies with him, but I recognize his enormous efforts and enthusiasm).

For the ‘classic’ OOP defenders that had attacked MiniGUI during years, I want to remember them, that VB turned in the most popular development tool in the world, based in a non-classic scheme for GUI handling, oriented to make things easier for the programmer, let him focus in the problem to solve instead to do it the language complexities. If we are in the xBase world is because this is that we want (or must want). MiniGUI must not be ‘corrected’ to be converted to a traditional paradigm. It is simply an alternative, and as such, we have right to grant its existence.

Regarding the future, It could not be better.

Harbour is in Beta 1, extremely solid and efficient. Surely we have the final version soon.

Regarding MiniGUI, is extremely stable and reliable too. Since I successfully adapted it to work with MingW, we have now with a completely free package (Harbour + MiniGUI + MingW).

Finally, I want to thank to all people that collaborated in some way and whose contributions are documented in five years of ‘changelogs’ and (of course) an special thanks to Pepe Ruano, creator and administrator of harbourminigui.com

There is a lot to do, but I can say with satisfaction that my old dream, a Clipper for Windows free and easy to use, has been reached.

Thanks To All.

Roberto Lopez

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Note: This article borrowed by courtesy of author.

           Published at :  March 03, 2007 here.

What is Clipper ?

As a computer software term, the word “Clipper” has two meaning :

1- A programming language

2- A compiler

As a computer programming language that is used to build software programs that originally operated primarily under DOS. Although it is a powerful general-purpose programming language, it was primarily used to construct  database/business programs.

Clipper was originally released in 1985 as a compiler for dBASE III, a very popular database language at the time. Compiling dBASE code changes it from interpreted code, which must be interpreted every time each line of code is executed, to p-code, which uses a Virtual Machine to process the compiled p-code. p-code is considerably faster, but still not as fast as the machine code generated by native compilers. As a technical marketing ploy, the p-code was wrapped into object code (linkable .obj files) which gave the impression that it was compiled to native code. Clipper was created by Nantucket Corporation led by Barry ReBell (political) and Brian Russell (technical), and later sold to Computer AssociatesGrafX Software licensed CA-Clipper in 2002 from CA for ongoing marketing and distribution.

As the product matured, it remained a DOS tool for many years, but added elements of the C programming language and Pascal programming language, as well as OOP, and the code-block data-type (hybridizing the concepts of dBase macros, or string-evaluation, and function pointers), to become far more powerful than the original. Nantucket’s Aspen project later matured into the Windows native-code Visual Objects compiler.

After “swallow” Nantucket at 1992, CA published a few releases of Clipper Compiler, lastly 5.3a at  May 20, 1997. But most of Clipper programmer uses preferably 5.2e – released February 7, 1995.

Although remained a DOS as the compiler, Clipper continues to live as the programming language.

The Clipper language is being actively implemented and extended by multiple organizations/vendors, like xBase ++ from Alaska Software and FlagShip, as well as free(GPL-licensed) projects like Harbour and xHarbour.

Many of the current implementations are portable (DOSWindowsLinux (32- and 64-bit), Unix (32- and 64-bit), and Mac OS X), supporting many language extensions[1], and have greatly extended runtime libraries, as well as various Replaceable Database Drivers (RDD) supporting many popular database formats, like DBF, DBTNTX, DBFCDX (FoxPro, Apollo and Comix), MachSix (SIx Driver and Apollo), SQL, and more. These newer implementations all strive for full compatibility with the standard dBase/xBase syntax, while also offering OOP approaches and target-based syntax such as SQLExecute().

Version history

The various versions of Clipper compiler were:

From Nantucket Corporation; the “seasonal versions”, billed as “dBase compilers

  • Nantucket Clipper Winter’84 – released May 25, 1985
  • Nantucket Clipper Summer’85 – released 1985
  • Nantucket Clipper Winter’85 – released January 29, 1986
  • Nantucket Clipper Autumn’86 – released October 31, 1986
  • Nantucket Clipper Summer’87 – released December 21, 1987

From Nantucket Corporation; Clipper 5

  • Nantucket Clipper 5.00 – released 1990
  • Nantucket Clipper 5.01 – released April 15, 1991
  • Nantucket Clipper 5.01 Rev.129 – released March 31, 1992

and from Computer Associates; CA-Clipper 5

  • CA Clipper 5.01a –
  • CA Clipper 5.20 – released February 15, 1993
  • CA-Clipper 5.2a – released March 15, 1993
  • CA Clipper 5.2b – released June 25, 1993
  • CA-Clipper 5.2c – released August 6, 1993
  • CA Clipper 5.2d – released March 25, 1994
  • CA-Clipper 5.2e – released February 7, 1995
  • CA Clipper 5.30 – released June 26, 1995
  • CA Clipper 5.3a – released May 20, 1996
  • CA Clipper 5.3b – released May 20, 1997

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Note: This post is based upon mainly a Wikipedia article :

http://en.wikipedia.org/wiki/Clipper_(programming_language)