Installing the Software

FiveWin automatically installs in your computer generating the following directories trees:

It is best that every time you install FiveWin, you select adifferent directory, and that you try the new version for a while before destroying your previous versions. Normally there are no compatibility problems with previous versions, but sometimes there may be some changes.

· Very important: As soon as you install the software, read the file WHATSNEW.TXT in order to know what bug corrections, enhancements and modifications have been made.

· The latest process here is to modify the SAMPLES\Build.bat to SET appropriate your PATHS. Edit SAMPLES\Build.bat and modify the PATHS.

· If everything is installed properly, you may go to the SAMPLES directory, and try to build any sample:

SAMPLES\Build Tutor01

This generates a stand alone EXE file, Tutor01.EXE, that will automatically run showing this:


Required Tools

More:


Hardware requirements :

· FiveWin works from 386 computers and up. We do not support 286 computers.

· FiveWin may work in computers with 2 megs of RAM, though a minimum of 4 megs is highly recommended.

· FiveWin works in computers with DBLSPACE double spaced hard disks.

· FiveWin has been successfully tested with:

- Windows 3.1

- Windows 3.11 for WorkGroups

- Windows 95/98/ME

- Windows NT/XP/2003

· FiveWin has been successfully tested in Windows for WorkGroups NetWork, Windows 9x NetWorks, Windows NT/2000/XP/2003 NetWorks and Novell Network.


Software requirements:

· CA-Clipper 5.01, CA-Clipper 5.2 or CA-Clipper 5.3.

· A Windows linker is required: We highly recommend Blinker 3.0 and above versions. Blinker 3.XX is the Linker we normally use with our MsDos and Windows.

· Microsoft LINK.EXE 5.10 version and above work fine with FiveWin. You may download it from here: ftp://ftp.microsoft.com/softlib/mslfiles/lnk563.exe

· If you use LINK version 5.10 you need to use the SOURCE\TOOLS\ExeType.exe utility we provide to change the internal EXE version generated by the LINKer: ExeType.exe MyApp.exe 3.1 // Call this after generating the EXE

We do not support Borland's TLINK.EXE.

Symantec C++ 7.0 OptLink is compatible with FiveWin. Version 6.0 it is not compatible.

· A Windows Resource Editor is HIGHLY recommended. We normally use Borland's Resource WorkShop. We have also successfully tested Microsoft Visual Studio resource editor. These tools come with Borland's C/C++ compiler or Microsoft Visual C++ compiler.

We normally use Borland C++ 5.0/5.5. And all the C code included in FiveWin has been developed using Borland C/C++ compiler.

These products include excellent Windows Resources editors, that you need to do Visual programming.

These products offer a lot of very useful documentation, tools and of course, the C/C++ compiler, that you may use to enhance FiveWin developing new API C and DLLs C functions.

We do recommend you to acquire one of these compilers. They will offer you many, many benefits.


Dos Coding and Windows Testing

Clipper programmers traditionally select certain tools to build their own workbench environments. These are the tools that we strongly recommend to be used in Windows programming:

Source code editor MultiEdit for Windows (+ Evolve for Windows) (c) American Cibernetics www.multieditsoftware.com/

File Manager Total Commander (c) Christian Ghisler www.ghisler.com

Resources Editor Borland's Resource WorkShop

Linker Blinker 3.3 and above (c) Blink Inc www.blinkinc.com

Clipper.EXE, Blinker.EXE and MsLink.EXE, are DOS EXEs, and they must be executed from within a Dos task.

Normally we keep one or two Windows MsDos tasks. Pressing Alt-TAB you may quickly switch from MsDos into Windows and viceversa.

We recommend you to create a Windows program manager new group, where you place the icon of your FiveWin development application, plus an icon for accessing MsDos, and another for the Windows resource editor you use.

A great new benefit of Windows 9x is that you can automatically invoke your Windows EXE from inside a MsDos task. So you may modify the SAMPLES\BUILD.BAT we provide to automatically start your application after linking it. So, no Alt-TAB pressing may be required to switch to Windows.

We have compared our development cycle (editing-compiling-linking- testing) speed with other Windows development tools and platforms, and we are proud to say, that by far, CA-Clipper and FiveWin are the fastest Windows development tools for a professional programmer.


The Business-application point of view

Though Windows offers a lot of new and powerful capabilities, we insist in the idea that business-application components are still the same. We keep this idea very much in mind in order to be highly productive as xBase programmers.

In other words, we mean that you may try to cover the main parts of your application as you normally do, and later you will enhance your application with all the new fancy and powerful Windows new features.

More:


What are the basic parts of a business application ?

Of course, the heart of a business applications is the database design and implementation, and here CA-Clipper is, with no doubt, the king. In FiveWin you may keep all your existing database strategies and programming systems you normally use (though we will show how to get much more database development power then what you have, through FiveWin database objects and Windows Non-Modal designs).

Lets focus now on the user interface, and in all of the different parts of a Windows application. The more Windows applications you start developing, you will discover you always go through the same steps:

1. The main Window: In Windows, an application is always associated with a Window. We will see all the different kind of Windows you may build and how to build them.

2. The PullDown Menu: From the main Window the user may select through a PullDown menu all the different options of your application.

3. The Main Window ButtonBar and MessageBar are two components that you will find in many Windows applications. FiveWin provides all the necessary ingredients for building great looking and performing ButtonBars and Messagebar. The ButtonBar usually executes actions that you also provide through the PullDown menu.

4. From the main Window you will open DialogBoxes to interact with the user. Coming from Dos, now you are used to work with 'Modal' execution which means: Do just one thing at a time. But in Windows you may also take advantage of the Non-Modal execution. This means you may have several DialogBoxes at the same time.You will learn how easily this can be done in FiveWin.

5. In some of these DialogBoxes you will use Browses. Normally a business application uses Browses extensively. You will learn to use FiveWin's powerful browses, which let you design any kind of browse you may need.

6. To have a complete business application you need printing. All kind of reports, listings and printouts. FiveWin offers you a powerful built-in report engine to design any kind of business report in just few minutes.


A typical Windows business-application structure:

DataBase design and implementation -plus- Multi Document interface MDI design.

It is very important that you focus now on these parts, to quickly start building business applications. As you go on from here, you will start learning many new things that you will surely be adapting to your applications.


The main window

Normally, to build your main window application you do as follows:

#include "FiveWin.ch"

static oWnd

function Main()

DEFINE WINDOW oWnd TITLE "My application"

ACTIVATE WINDOW oWnd MAXIMIZED

return nil

In this sample you are selecting the most typical window, with default coordinates and style, and you start it at full open screen mode -MAXIMIZED-. If you want to place it at some position you may specify:

... FROM nTop, nLeft TO nBottom, nRight ...

FROM 2, 2 TO 20, 60

We simulate in these coordinates, text mode coordinates.

ACTIVATE WINDOW will invoke automatically the main application event loop if it is not working yet. Internally, the application only need one event loop for all the windows.

There are three main different ways to build your application window:

· Defining a standard window (like the sample above).

· Defining a MDI window: A multi document interface, this means a main window that will allow several child windows running inside it. For instance, Windows Program Manager is a MDI window.

· Defining a DialogBox as the main application window: There are some situations where you don't need to implement a main window, with pulldown menu, buttonbar, etc... and you just need some operations to be done, and just a DialogBox should be the perfect way.

FiveWin lets you start the application with all these above styles.

In the sample above the style of the window as default is OVERLAPPED- WINDOW which means all the typical features you find in a window: caption, system menu, resizable border, min and max buttons.

If you want to specify other styles, FiveWin offers you some clauses to select them:

· NOSYSMENU

· NOCAPTION

· NOICONIZE

· NOZOOM

Also you may specify the combination of them you want, just doing:

... STYLE nOr( WS_BORDER, WS_MAXIMIZE, ... )

These styles are defined inside INCLUDE\WINAPI.CH header file -which is automatically loaded by FiveWin.ch.-

If you want to start a MDI -Multiple interface document- window, you just have to specify the clause MDI:

DEFINE WINDOW oWnd TITLE "A MDI environment" MDI

ACTIVATE WINDOW oWnd // let's open it now in normal mode

// You may also select ACTIVATE WINDOW oWnd ICONIZED

// which will start the application as an icon.

See the source code of IDE\SOURCE\IDE.prg if you want to see how to build and properly manage MDI environments. We also supply some samples in SAMPLES\TestMdi_.prg.

MDI environments require some level of Windows expertise from the users of the application. If your customer is new to Windows, you may do better trying the standard main window way.

FiveWin will automatically control all Windows messages that it receives. But, based on a xBase syntax, you may specify certain behaviors ON some events occurring.

ACTIVATE WINDOW oWnd ;

ON PAINT ... ;

ON LEFT CLICK ... ;

ON RESIZE ... ;

See FiveWin.ch for a list of all the events we support. Normally this kind of control will not be necessary, but in some circumstances you may need it.

Also, the main window of your application may include scrollbars. The typical Windows scrollbars on the edges of a window have to be built when defining the window:

DEFINE WINDOW oWnd ... VSCROLL

or

DEFINE WINDOW oWnd ... HSCROLL

or both of them

DEFINE WINDOW oWnd ... VSCROLL HSCROLL

If you select these styles, you may intercept the events they will generate through these clauses:

ACTIVATE WINDOW oWnd ...

ON UP ...

ON DOWN ...

ON LEFT ...

ON RIGHT ...

ON PAGEUP ...

ON PAGEDOWN ...

If you specify these styles, your window object oWnd will have defined two scrollbars objects:

oWnd:oVScroll and oWnd:oHScroll

So you may control and modify them directly -see scrollbars management-

To end the execution of your main window -or any other window or DialogBox- you use the :End() method: oWnd:End()

This tells the window object oWnd to finish working. If you specified a VALID clause when activating the window, the VALID clause will have to return .t. to allow ending the window. This is a typical situation:

ACTIVATE WINDOW oWnd ;

VALID MsgYesNo( "Do you want to end ?" )

During your application, if you call oWnd:End(), or the user double click the window close button, or if the user decided to end Windows, the VALID will be executed and according to its result it will let or not end the window. Remember you may use oWnd:End() to end any kind of window or DialogBox: oDlg:End().

There is no way to build the main window from resources, unless you start your application with a DialogBox:

DEFINE DIALOG oDlg RESOURCE "main"

ACTIVATE DIALOG oDlg CENTERED

In this situation, we are loading as a main application window the dialog box stored in resources as "main".

Use a DialogBox as your main window only when you don't need a pulldown menu, neither a message bar or a buttonbar. Remember that normally a DialogBox will not maximize or iconize, so plan carefully what kind of window you may use as your main application window.

Most of the time a normal window -as the first sample above- will be perfect.


The Pulldown menu

The typical structure of a Windows program is to build a Window and to assign it a main menu that will be useful as main organizer of the application.

From the menu, the user can select the different tasks of a program. Thanks to the pulldown menu structure of Windows we can implement an easy and intuitive user interface.

You should try to use good design techniques for the main menu of your application. Don't make it too complicated. The idea is to implement just a few main options at the bar menu so the user will easily select what he needs, and from there you should presents new submenus that will contain all the possible options.

FiveWin has been designed so you don't need to code DO CASE...ENDCASE options to select from the different actions the user may choose.

When a MenuItem is defined, we will specify the action we want to be automatically executed when the user selects that option. It is very easy to control all the possible options of the program.

MENU oMenu

MENUITEM <cItem> MESSAGE <cMessage> ACTION <uAction>

MENUITEM <cItem> MESSAGE <cMessage> // No action here

MENU // Submenu

MENUITEM <cItem> MESSAGE <cMessage> ACTION <uAction>

ENDMENU

...

SEPARATOR

MENUITEM <cItem> MESSAGE <cMessage> ACTION <uAction>

ENDMENU

MESSAGE & ACTION are optional clauses. If an Action clause is not defined, except in the case of a heading for a submenu, then nothing happens when you select that menu option.

You can have as many SubMenus as you need. To create a SubMenu you only have

to specify a new MENU ... ENDMENU combination under a MenuItem and complete it as usual.

MENUITEM <cItem> MESSAGE <cMessage>

MENU // The new Submenu starts here

MENUITEM <cItem> MESSAGE <cMessage> ACTION <uAction>

...

ENDMENU

MENUITEM <cItem> MESSAGE <cMessage> ACTION <uAction> // More Items

To activate the menu first you have to assign it to a Window. The easiest way to do this is when you are building your Window:

DEFINE WINDOW <oWnd> <otherClauses> ;

MENU BuildMenu()

...

function BuildMenu()

local oMenu

MENU oMenu

MENUITEM <cItem> MESSAGE <cMessage> ...

...

ENDMENU

Return oMenu

or you can do it later using the command:

SET MENU OF <oWnd> TO <oMenu>


The ButtonBar

The buttonbar has become one of the standard components that you may find in almost all Windows applications.

The purpose of the buttonbar is to provide a quick access to the most used choices of your application. Also it takes advantage of using images instead of words to show what they do.

A well designed buttonbar helps a lot in quickly understanding and managing an application.

Don't use images without meaning. Use intuitive drawings that lets everybody use the application easily.

A buttonbar is an area of the screen where there are some buttons with icons (FiveWin uses bitmaps) offering different actions. Normally when you move the mouse over those buttons, the message of the bottom bar is the same as selecting the same option from the pulldown menu.

FiveWin let us select a 3D looking buttonbar (see ButtonBar xBase commands) and to select the desired dimensions for its buttons. Also it is possible to use bitmaps that automatically adjust to the surface of the buttons.

Most applications use buttonbars that have the ability to changing its position on the screen. FiveWin lets you place a buttonbar at the Top, Left, Bottom and right position of the window that holds it, and optionally it may be a floating buttonbar. To select its starting position use the xBase commands we provide to manage it. To change its position on the fly just right click on it (not over the buttons). A popup menu will let the user make the position selection.

Also it is possible to destroy on the fly the buttonbar you may be using and replace it for a new one. All the windows have a :oBtnBar DATA that may be freely manipulated. Remember that to destroy any control we use the message :End().

The next version of FiveWin will offer new and powerful possibilities that we are working on (like rulers, multiple buttonbars, scrollable buttonbars, user guided configurable buttonbars, and more...).

Please let us know your needs, and feel free to send us any enhancement you would like us to review. A good designed and powerful buttonbar is a very important component of a Windows application.


The message Bar

The message bar has become also a standard component that we may find in almost all Windows applications.

A message bar is a control placed at the bottom of its container window that shows information related to the pulldown menu currently option selected or to the buttonbar button currently under the mouse cursor.

It is also possible to display the messages of a child Dialog Box controls, to help users to understand the meaning of each DialogBox control. (See DialogBoxes explanations.)

FiveWin automatically applies 3D look to the messagebar, and optionally lets selection of a left or center message position (see MessageBar xBase commands).

The next version of FiveWin will offer new and powerful possibilities for messagebar (like the ability of having multiples columns of information on it, and automatic timed messages).

In the source code of the FiveWin IDE you will find samples showing how to place a clock in the messagebar. We plan to extend FiveWin messagebar with all those features.

A well designed application that uses extensive information on the messagebar to help the user quickly understand, reduces training times for companies and makes software much more human oriented.


The Dialog Boxes

In Windows, the interaction with the user to get data is done using Dialog Boxes.

Dialog Boxes are specialized Windows containing certain controls through which the user completes some information. You should avoid using the main window of the program to collect data. Every time you are going to request some information, you will do it through a Dialog Box.

FiveWin implements support for Dialog Boxes constructed and stored as resources and also for Dialog Boxes directly constructed in the source code of your program.

We recommend you to get a resource editor and that you use it to build the Dialog Boxes of your program. Borland usually offers introductory offers, at a very good price, for its products to program in Windows and most of them include the Resource WorkShop which is an excellent resource editor. You should only design Dialog Boxes in source code if you are going to design very easy windows or if you don't have af resource editor.

In Windows, Dialog Boxes fall in two categories: Modal and Non-Modal Dialog Boxes. Modal Dialog Boxes are those that don't let the user do other things until they finish working in that dialog. In DOS we are used to using Modal Dialog Boxes.

Non-Modal Dialog Boxes let us do other things, so we can have many Dialog Boxes opened at the same time. DOS users are not accustomed to non-modal execution, but more and more users are demanding them.

A Dialog Box is an Object, so to create them you will use the typical syntax for creating Objects:

local oDlg

DEFINE DIALOG oDlg ;

[ FROM <nTop>, <nLeft> TO <nBottom>, <nRight> ] ;

[ NAME <cName> ]

<cName> is the name we have assigned to that Dialog Box assuming that we have built it

using a resource editor.

After that you have to assign the controls it is going to use. If you are designing it from your source code then you will use the familiar xBase syntax:

@ <nRow>, <nCol> ... OF oDlg

Remember to specify OF <oDlg> clause so the control will know which is its container Object.

If we built the Dialog Box using a resource editor then we have to redefine the controls to associate certain behaviors -review the Windows resources section of this guide-.

Once again everything is ready, we will activate the Dialog Box:

ACTIVATE DIALOG oDlg

That's all. Basically this is the system we are going to use with all Dialog Boxes. Review the examples we provide with FiveWin to understand how this process works in detail.

More:


ADDITIONAL NOTES ABOUT NO-MODAL DIALOGS

Making a NonModal Dialog is as easy as including the clause 'NOWAIT':

DEFINE DIALOG oDlg RESOURCE "Test"

ACTIVATE DIALOG oDlg NOWAIT // Non Modal!!!

Be careful about Non-Modal execution. It is very dangerous if the user is not an expert. When you call a Non-Modal Dialog Box, program execution does not stops there! So you can not Close a DBF you are using from Dialog Controls. Also, the user may select that option again and the Dialog Box will be created again and again. Because Clipper keeps 'live references' to local variables, there is no conflict with using NonModal Dialogs.

Non Modal Dialog Boxes and MD Windows -see how IDE works for MDI- is one of the BEST features of FiveWin.


Controls Management

In Windows, a distinct component of a Dialog Box through which the user interacts to select and complete certain information is a 'Control'

In Clipper, the only control we have really used is the typical GET. Through a GET the user completes certain information. In Windows this concept gets extended and, so, the user may interact with command buttons -PushButtons-, selection boxes -CheckBoxes-, single selection options -RadioButtons-, etc...

There is no limit to the variety of controls we can find or design in a program. Essentially, a control has been designed to obtain or show certain information to the user of the program.

In xBase, this kind of action usually has been identified with the syntax:

@ <nRow>, <nCol> GET ...

Now, in Windows xBase we extend that syntax towards new types of controls:

@ <nRow>, <nCol> BUTTON ... OF <ContainerObject>

@ <nRow>, <nCol> CHECKBOX ... OF <ContainerObject>

etc...

With every one of those lines of code we are building an Object. An Object that inherits from the FiveWin TControl CLASS is specialized in the way it interacts with the user. You don't have to worry too much about the existence of this Object, FiveWin controls all these processes automatically. However, it is convenient to understand the basis of this functionality.

Controls may be created from inside the same source code of your program, using the syntax we have shown you:

@ <nRow>, <nCol> <ObjectClass> ... OF <ContainerObject>

If you are using Dialog Boxes designed with a resource editor, then you have to REDEFINE certain behaviors of those controls, because those Objects are already 'built' inside Window's resources:

REDEFINE <ObjectClass> ID <nIdentifier> OF <ContainerObject> ;

....

Remember that in FiveWin the READ command is GONE. The program is in a constant state of interaction with Windows. A Dialog Box will start working when you activate it:

ACTIVATE DIALOG <oDlg>

Consult and review the examples we included with FiveWin. Through them you will understand the design and management of Windows controls.

Review the file FIVEWIN.CH which is located in the \FIVEWIN\INCLUDE directory to see the different syntax supported by FiveWin.


What are resources

Resources are one of the most important parts of Windows programming.To understand them you should consider that your program can be divided in two parts:

· What the program does -behaviors-

· The different pieces used to build the program -Data-

Once again we are talking about Object Oriented Programming. Obviously, both parts are highly dependant upon each other.

Some of the pieces used to build your program may be stored in a separate .DLL file or even inside the EXE file. Those pieces, let's call them resources, can be managed and changed externally from the program. This is probably the most important reason for the birth of what is called "Visual Programming".

"Visual Programming" is mainly about resources. The programmer may draw resources using the mouse and certain design programs. In the next stage, those resources get related to some behaviors. From that moment you are building, and using, Objects!

FiveWin has been designed to obtain high performance from Windows resources. FiveWin proposes a way of programming based on resource usage. We are convinced that drawing screens and other resources is the easiest and quickest way to develop a program. Thanks to this technology you can easily build 'Data-driven' programs. This means that your user interface is based on external and modifiable data. You can easily modify a screen and use it without having to recompile or relink.

The most important part of this process is to understand how to build an Object from a resource, and how to define -redefine- its behaviors. There are three main ways to build an Object in xBase:

1. @ nRow, nCol ...

This kind of construction builds an Object and displays it. When you do, @ ... GET ... you are building a GET Object with Clipper, and you also display it. This way of building Objects is not based on resources.

2. DEFINE <ObjectClass> <ObjectName>

This is the main way of building an Object in xBase. The Object is created, but it is not shown. To display it and activate it, you do:

ACTIVATE <ObjectClass> <ObjectName>

This system was proposed and used by dBase IV, and it is going to be the most important way to build Objects in xBase.This system it is also not based on resources.

3. REDEFINE <ObjectClass> <ObjectName> ID <Identifier>

In this case you are using resources. The Object is already created in the resource, but you need a way to modify and define its behaviors. This is why the REDEFINE command is going to be the most important command to modify behaviors in xBase.

Once you have redefined its behaviors, the Object will be activated using the command:

ACTIVATE <ObjectClass> <ObjectName>

In many cases the Objects are contained by a 'container' Object.This would be the case of a Window or a Dialog Box which contains certain controls. To activate those controls it is not necessary to use the command ACTIVATE ... for each of them. It is enough to ACTIVATE the container Object.

Lets review now, step by step, the process you should follow to use resources in your programs:

1. You need a resource designer. We like to use Borland's Resource WorkShop. This designer comes with Borland's products for Windows, such as C++ and Turbo Pascal. You should contact Borland or a software distributor and get one! You'll thank us!

2. Using that designer you may start drawing the different screens of your program. This is a standard system for Windows programming. The screens you design must be stored inside a DLL. In the \FiveWin\DLL directory there is an 'empty' DLL you may use to store your screens in. (make a copy for every new project). You should tell the resource editor to 'open' and use that DLL. Select open file and type the name of that DLL.

3. When you design your screens you should give a name to each of them. This name will let you select them from inside your program. You should specify a unique identifier, a number, for each element of a screen. This number will be used by the REDEFINE command to tell FiveWin which Object you are using.

Practice with your resource editor to understand it and to become familiar with its usage.

After that, from inside your program you should tell FiveWin that your program is going to use resources. To do this, use the following command at the beginning of your program:

#include 'FiveWin.ch'

SET RESOURCES TO <DLLFileName>

And when you are about to end the execution of your program, you should tell FiveWin that you have finished using them:

SET RESOURCE TO // Release the resource

To use any of the Dialog Boxes you have defined in your DLL all you have to do is the following:

function TestDialogBox()

local oDlg

local cName := "FiveWin"

DEFINE DIALOG oDlg NAME "MyDialog"

REDEFINE GET ID 110 VAR cName OF oDlg

REDEFINE BUTTON ID 120 OF oDlg ACTION nMsgBox( "Hello" )

REDEFINE BUTTON ID 130 OF oDlg ACTION oDlg:End()

ACTIVATE DIALOG oDlg

Return nil

In this example we are building a Dialog Box from the screen "MyDialog" stored inside the DLL we have specified in a SET RESOURCES TO "MyDLL.dll" earlier in the program.

In that screen there is a GET Object and two PushButtons (Command Buttons). From the resource editor we have assigned a value of 110 to the GET control and 120 to the first button and 130 to the second.

Remember that the syntax for redefining is:

REDEFINE <ObjectClass> <ObjectName> ;

ID <Identifier> ;

OF <ContainerObjectName> ;

...

Every kind of control will have certain extensions typical to this command. As an example, BUTTON has the clause ACTION to let us specify what the Object will do when the button is pressed.

Review the source code of \EXAMPLES\FwBorl.prg where you will find several examples of using resources from DLLs.

When you get used to this system you will understand that it is the easiest and quickest way of building programs.


EXE Resources vs. DLL Resources

There are two main ways to store the resources of your applications:

1. Inside your .EXE file

2. Inside an external DLL

Both systems are very powerful, but there are some important differences you should know:

1. The biggest benefit of storing an .RC file (using Microsoft resource compiler RC.EXE -included with Microsoft, Borland, Symantec...-) is that you may use DEFINEs as a replacement for the controls IDs.This means you don't have to remember 'strange' numbers, and also that under any source code or resources modification you will make fewer mistakes.

Sample:

REDEFINE GET cName ID 110 OF oDlg // using an ID number 110

Instead of that:

#define ID_NAME 110

REDEFINE GET cName ID ID_NAME OF oDlg

his one has the benefit that you may create a .CH file with all those #define's and the resource editor let you use it when modifying the .RC file:

MyApp.RC

#include "WinApi.ch" // provided with FiveWin

#include "MyApp.ch" // your IDs definitions are here !!!

Clients DIALOG ...

CONTROL ... ID_NAME,

Based on our experience we do recommend storing a .RC file inside your .EXEs because it is much easier to control IDs and avoid errors.

The SAMPLES\Build.bat batch file we provide with FiveWin, automatically will call RC.EXE if detects a file with extension .RC with the same name of our application. Basically what we do in build.bat is:

RC -K MyApp

This will store MyApp.RC resources inside your MyApp.EXE file.

There is no need to specify a command SET RESOURCES TO ... in your application if you take this route, because your EXE file already knows how to locate the resources inside itself.

The only disadvantage of this system is that every time you build your EXE you have to compile the RC and place it inside the EXE again -though this process is extremely fast!-

2. The big benefit of storing resources inside a DLL is that you may really have Data Driven DialogBoxes, because if you modify the DLL resources (using your resource editor) there will be no need to recompile again your EXE! This may be a great advantage when developing very large applications.

We provide an empty DLL to be copied when you develop a new application as an empty storage system where you may place all your resources:

COPY screens.dll MyApp.dll // we provide an 'empty' screens.dll

Now you edit it with your resource editor:

WorkShop MyApp.dll // Or open it as a DLL

Later in your application you specify:

SET RESOURCES TO "MyApp.dll"

And you are ready to start using your resources. Remember that if you decide to put your resources inside your app (using .RC and RC.EXE) there is no need to specify SET RESOURCES TO... as the .EXE already has all them inside.

The great disadvantage of this system is that you are not allowed to use labels if you use a DLL to store resources ! Neither Borland resource editor nor Microsoft let you use a .CH or .H file where you may store your #define's if you store your resources inside a DLL.

Both systems are excellent, and we do recommend you to test both of them and decide by yourself which system suits better your needs.


Multimedia applications

Multimedia applications typically refers to applications that extensively use sound and vision to interact with the final user. But, in fact, a multimedia application may use more ways to get a better interaction with the final user mainly using new external devices controlled by the application, such as touch screens, electric pens, plastic card readers, fax-modems, voice recorders, artificial vision, etc...

FiveWin offers all the necessary extensions to develop sophisticated multimedia applications. Here we are going to see how to use sound, vision and how to manipulate any external device we may find useful. Also, we are going to explain some techniques that conveniently used will let us make our applications look like any Multimedia app we may have seen.

Sound: There are two principal ways to reproduce sounds in our apps: Playing a WAV file and playing a MDI file.

WAV files are digital recordings of sounds. A WAV file it may be a person voice, a song, noises, etc... We have the following functions to reproduce them:

· SndPlaySound( <cFileName>, <nMode> ) --> <lSuccess>

Plays a WAV file from disk. See Functions2 section SndPlaySound() full explanation)

· MsgSound() which it is exactly as the above SndPlaySound()

Plays a WAV file from disk but using the FiveWin Msg... functions style.

· SndPlayRes( <cResName>, <nMode> ) --> <lSuccess>

Plays a WAV file from resources. See Functions2 section SndPlaySound() full explanation)

Vision: There are two principal ways to display images in our apps: Managing Bitmaps BMP files and reproducing animated Video files.

BMP bitmaps files are the way Windows uses to store digital pictures and later show them again at the screen or at the printer. You may store your digital images at any other file format (using some convenient DLLs libraries) but later they will be turned into bitmaps as Windows is the only way that knows to manipulate them. We have the following bitmaps support:

· Class TBitmap: Controls that show a related bitmap file.

· Class TBtnBmp: Controls that show one or two bitmap files,and that behaves like a PushButton, thus the user may click them and perform an action.

· Functions to dynamically load and display a bitmap:

LoadBitmap( <hInst>, <cBmpName> ) --> <hBitmap>

(see Functions2 section LoadBitmap() full explanation)

DrawBitmap( <hDC>, <hBitmap>, <nRow>, <nCol>, <nWidth>, <nHeight>, <nRaster> ) --> nil

(see Functions1 section DrawBitmap() full explanation)

PalBmpDraw( <hDC>, <nCol>, <nRow>, <hPalBmp>, <nWidth>, <nHeight>, <nRaster> ) --> nil

(see Functions2 section PalBmpDraw() full explanation)

DeleteObject( <hBitmap> ) (for LoadBitmap(), for a TBitmap object see TBitmap METHOD End() )

(see Functions1 section DeleteObject() full explanation)

AVI Animated video files is the way Windows stored a sequence of bitmaps mixed with audio (recorded from a video camera, cartoons, etc...). FiveWin implements the Class TVideo to easily reproduce them. (See Class TVideo full explanation).

Windows has a powerful subsystem named MCI (Media Control Interface) that lets you easily access to any kind of device which it is MCI compatible. The first thing you should do when studying a new device to manipulate is to check if it is MCI compatible. FiveWin implements the Class TMCI to easily manage any kind of MCI compatible device (See Class TMCI full explanation).

To finally make your application look in a unique way (the final user will not recognize that he is using a Windows application) there are some easy techniques that could be used. You can easily avoid using a frame in your main window, so there will not be a visible caption and typical Windows small pushbuttons on the corners. Basically this can be done doing:

DEFINE WINDOW oWnd STYLE nOr( WS_POPUP, WS_VISIBLE ) COLOR ...

ACTIVATE WINDOW oWnd MAXIMIZED ;

ON PAINT ... (you could draw a full Bitmap on the window surface,

you could fill it with certain drawing effects, etc...)

See SAMPLES\Install.prg for a working sample of this technique of avoiding display the window frame and related buttons.

Multimedia applications open a wide range of possibilities where only your imagination and your Windows expertise are the limits. Once you start practising with these concepts you will easily recognize these elements on most existing Multimedia applications, and you will start incorporating them in your own FiveWin apps.


Reusing all your MSDos designs

FiveWin imposes no restriction at all to your current DataBase designs and techniques acquired in MsDos. You may feel free to continue working as you normally do with DataBases.

There are just some points you should keep in mind for a better understanding of Windows processes:

By default any Windows task is given a maximum of 20 files opened at the same time. In order to have the same conditions as we have in MsDos you have to use the SetHandleCount() function that FiveWin supplies:

SetHandleCount( <nMaxFiles> ) --> <nMaxFilesAutorized>

If your application is going to manage 40 files at the same time, you will have to do at the beginning of your application:

SetHandleCount( 40 )

Remember that DBFs that use memos also open an associated file DBT, and also remember that normally when Windows is printing it opens some temporary files (also FiveWin opens some more when doing PREVIEWs of printing works). If you get an error it may be that there are not enough files available. Increase its number with SetHandleCount(). There is a maximum of 255 files available per application.

Also it is not a good idea to give 255 files to all your applications for you will consume a lot of memory resources!

If you are working with NonModal designs, the same DataBase may get opened several times at the same time! By the same user! Clipper allows this but, in fact, your application is acting like an application for a NetWork. You have to provide Multi-User control to your application!

For this, if you are using Windows 3.1 loading SHARE.EXE before loading Windows, this is a MUST! If you are using Windows 3.11 or Windows 9x this is no needed as these new versions automatically load SHARE.EXE when starting.

Converting an application for working in a NetWork is quite easy. Review this documentation for our recommendations and guidance for NetWork programming. Don't worry if you have never code a multi-user application. It is really easy!

FiveWin offers you a powerful DataBase Class that in fact saves you a lot of tedious work. Just give a little of your time to understand the FiveWin DataBase Class and you will save a lot of your precious time!

DataBase objects saves you from coding a _lot_ of source code lines! Go for DataBase objects right now!

If you are working with older versions of CA-Clipper (older than 5.2 d) you may have serious troubles working with some CA-Clipper RDDs. Some of them cause big problems in MsDos but in Windows they may crash your system. DbfCdx is not working properly even in version 5.2 d. There is a late patch for 5.2 d but we have not tested it yet, since we work most of the time, with Comix and SixDriver.

We do recommend working with compound indexes CDX as they save a lot of work. Get Comix or SixDriver and use them! They are excellent!


Using FiveWin DataBase objects

FiveWin DataBase objects have been designed with the purpose of reducing the size of your code when you have to manipulate a DBF. They simplify very much all the work required to work with DataBases and they are totally compatible with the standard way of manipulating DBFs in Clipper.

More:

1. What is a DataBase Object ?

2. How do I create a DataBase object ?

3. Why a FiveWin DataBase object reduces my code ?

4. What cautions may I have when using DataBase objects ?

5. Where can I find a working sample ?


1. What is a DataBase Object ?

A DataBase object works mainly as a buffer, where you manipulate the Data, and lately you save it to the real DBF.


2. How do I create a DataBase object ?

After you do the typical USE <cDbfName> ALIAS ..., then following this sentence you write:

local oDbf

USE <cDbfName> [ ALIAS ... INDEX ... ... ]

DATABASE oDbf

FiveWin will create automatically a DataBase object and will keep its reference inside the oDbf variable.

The DataBase object will have as DATA the name of the fields of your DBF. Sample:

USE Customer // Customer has a field called "First"

DATABASE oDbf

oDbf:Load() // Loads values from the real DBF

MsgInfo( oDbf:First ) // There is a DATA "First" there,

// ready to be used!


3. Why a FiveWin DataBase object reduces my code ?

Traditionally all Clipper programmers need to declare and use LOCAL variables as buffers where they manipulate the DBF values, and later they save the contents to the real DBF. This is a must if you are coding for NetWorking, as you can not manipulate the fields directly when you are sharing a DataBase (you have to lock, replace and then unlock).

Another alternative used by Clipper programmers is to use an array as a buffer, where they load the initial DBF values, then they are manipulated and later they are saved to disk. Normally those operations are named Scatter() and Gather().

The disadvantage of using arrays is that you can not use your fields names directly, instead you have to define labels (#defines) with the risk of altering those sequences and generating errors.

FiveWin DataBase objects solve those problems totally, as you no longer need to declare local variables one for each field. You just need to declare one local variable for holding the DataBase Object.

In fact, the DataBase object keeps internally an array, in the same way as you would use an array for a buffer, but with the benefit that now you can use the names of the fields to manipulate each field!


4. What cautions may I have when using DataBase objects ?

Clipper restricts symbols names up to 10 characters length, so you can not use fields names with 10 characters, as in Clipper OOPS when you are assigning a DATA, Clipper internally places an underscore at the beginning of the DATA name:

// ABCDEFGHIJ ==> Your field name

MsgInfo( oDbf:Abcdefghij ) // Will work fine!

oDbf:Abcdefghij = ... // Will not work!

// as Clipper will do:

// oDbf:_Abcdefghij

// so exceeding 10 characters

Remember: If you are going to use FiveWin DataBase objects then you can not use fields with names longer than 9 characters !!!


5. Where can I find a working sample ?

Look at SAMPLES\Dbf01.prg for a working sample using a FiveWin DataBase object.

Enjoy DataBase objects, they are extremely powerful and saves you from a lot of work! And they are 100% compatible with your existing code !!!


DataBases and Non-Modal programming

If you choose to develop your application using a Non-modal style you may be aware of certain design rules:

More:

1. What is a Non-modal application ?

2. How a non-modal design affects my DataBases manipulation design ?

3. Does Clipper offer DataBase capabilities for Non-modal programming ?

4. How difficult is coding for a NetWork ?


1. What is a Non-modal application ?

If you use MDI windows in your app, or if you use DialogBoxes with the clause NOWAIT, then you are implementing Non-modal designs.

A non-modal design will let user select several things at the same time. If you place a browse inside a MDIChild window, that MdiChild window may be opened several times! Or if a DialogBox is editing a certain Database, it may be issued several times.


2. How a non-modal design affects my DataBases manipulation design ?

A non-modal design works exactly as if you were workin on a NetWork, so NetWork programming rules have to be used. If a MdiChild window opens several times (at the same time) the same DataBase it will be the same situation as if different users were being opening several times those Databases on a NetWork.


3. Does Clipper offer DataBase capabilities for Non-modal programming ?

Yes! Clipper let you open the same physical database in different alias, though acting in the same way as if you were working on a NetWork.

Important: In order to let Clipper manage the same DataBase on different alias, you HAVE to specify different ALIAS:

USE Customer ALIAS Cust1 NEW

USE Customer ALIAS Cust2 NEW

From that moment you have to use Cust1 or Cust2 to reference your fields.


4. How difficult is coding for a NetWork ?

If you have never coded for a NetWork, don't be afraid. In next item in this documentation we explain the foundation for doing NetWork coding with Clipper. It is quite easy!


Network programming

If you have never design a NetWork application with Clipper, don't be afraid! They are not so difficult. There are some rules you have to follow:

1. All DataBases will be opened 'SHARED' by default, except if you specify 'EXCLUSIVE' clause, and also depending on your SET EXCLUSIVE ... state (see USE... and SET EXCLUSIVE... Clipper commands).

2. Once the DataBase is USEd as SHARED, several users on a NetWork may use it, or several non-modal MdiChild windows or Non-modal DialogBoxes may access the DataBase info at the same time.

3. You can not manipulate the contents of a field directly. Before replacing the value of a field you have to lock the record. Basically this is the typical procedure:

4.

if MyAlias->( RLock() ) // Lock the record

MyAlias->Field := <NewValue> // Modify the contents

MyAlias->( DbUnLock() ) // UnLock the record

else

MsgAlert( "The DataBase is in use now! Try again!" )

Endif

4. Some Database operations (as building an entire INDEX) may require that you open a DataBase in EXCLUSIVE mode or that you lock the entire Database, not just a record.

Use USE ... EXCLUSIVE to open a DataBase as exclusive or use the function FLock() to entirely lock a file.

5. Get yourself some book about NetWork coding for learning advanced tips and tricks! You will become a NetWork programming master pretty soon!


FiveWin own TWBrowse class

FiveWin implements its own browse which has some important differences from the traditional MsDos Clipper TBrowse. This difference is based on the fact that we wanted FiveWin browsers to execute as fast as possible. Windows is a graphical environment, so applications user interface tends to be slower than their MsDos equivalents. If you want to work in the MsDos way, FiveWin also provides a new class TCBrowse, which it is a column based browse.

FiveWin TWBrowse does not work with column objects, instead of those, it holds an codeblock (DATA bLine) which returns an array. The contents of this array is used to display each visible column content. This makes an important difference: Lets suppose we have a 10 columns browse, which also has 25 rows on the screen. If we were working with traditional browse to fully repaint the browse we were doing the following:

10 columns x 25 rows = 250 codeblocks evaluations.

FiveWin TWBrowse = 25 codeblocks evaluations only !!!

This fact makes FiveWin TWBrowses extremely fast, though it changes a little the way you are used to work with browsers. The main idea is that DATA bLine holds a codeblock that returns an array:

<oBrw>:bLine = { || { "One", "Two", "Three", ... } }

The second difference is that being in a graphical environment our users wanted to also show bitmaps (graphics) as browse elements. How could we distinct from normal data and bitmaps handles ? The solution was that a character string holds normal data, and numeric values are considered bitmap handles:

<oBrw>:bLine = { || { nHBitmap, "One", "Two", "Three", ... } }

When FiveWin TWBrowse evaluates this codeblock, it detects there is a numeric value as an element of that array, so that number is treated as a handle of a bitmap, and it is automatically painted on its column position. As you can use expressions to return that numeric value, you have an easy way to paint different bitmaps based on any condition:

<oBrw>:bLine = { || { If( Clients->Balance > 0, hBmpPlus, hBmpNeg ),;

Clients->Last, Clients->First,;

Str( Clients->Balance ) } }

Important: Always use character expressions as elements for the bLine array! A number will means a bitmap handle. An invalid bitmap handle (if by mistake you supply a number instead of a string expression)will cause strange results!

Besides this difference, the TWBrowse object is almost identical to a MsDos Clipper TBrowse. We have just used 'Hungarian notation' (we specify the type of a DATA -instvar- preceding the DATA name) to specify the type of each TWBrowse object DATA:

FiveWin TWBrowse | Clipper MsDos TBrowse
bGoTop | GoTopBlock
BgoBottom | GoBottomBlock
Bskip | SkipBlock
nTop | nTop
nLeft | nLeft
nBottom | nBottom
nRight | nRight
nRowPos | RowPos
nRowCount() | RowCount
nColPos | ColPos
lHitTop | HitTop
lHitBottom | HitBottom
nClrText | nClrPane
nClrBackHead | NClrBackFocus
nClrForeHead | NClrForeFocus
GoUp() | Up()
GoDown() | Down()
GoTop() | GoTop()
GoBottom() | GoBottom()
GoLeft() | Left()
GoRight() | Right()
PageUp() | PageUp()
PageDown() | PageDown()
Refresh() | RefreshAll()
DrawSelect() | RefreshCurrent()
SetCols() (All of them) | SetColumn()
GetColSizes() | ColWidth()
FiveWin TWBrowse | Clipper MsDos TColumn
aHeaders (All of them) | Heading
bLine (All of them) | Block
aSizes (All of them) | Width

Beside these, FiveWin TWBrowse offers much more built-in functionality that traditional MsDos Clipper browse. The following methods are not available on Clipper msDos TBrowse:

· KeyDown()

· KeyChar()

· LButtonDown() (MOUSE)

· LButtonUp()

· MouseMove()

· LDblClick()

· RButtonDown()

· RButtonUp()

· nAtCol()

· lEditCol() (Automatic editing)

· VScroll() (SCROLLBARS)

· HScroll()

· Skip()

· SetFilter() (Index based )

· Report() (Automatic Reporting)

· SetArray() (Arrays editing)

· SetTree() (Trees)

Finally, FiveWin implements easy xBase commands to build a whole browse with just one xBase command (there is no equivalent for this in MsDos Clipper TBrowse):

From source code: @ <nRow>, <nCol> LISTBOX <oLbx> ;

FIELDS <Expression,...> ;

HEADERS <Title,...> ;

COLSIZES <Size,...> ;

etc...

From Resources: REDEFINE LISTBOX <oLbx> ;

FIELDS <Expression,...> ;

HEADERS <Title,...> ;

COLSIZES <Size,...> ;

etc...

See FiveWin Browse xBase commands and the Class TWBrowse explanation in this manual for a full description of the above xBase commands. Remember that FiveWin also provides a new powerful Class TCBrowse in case that you want to work with column objects. TCBrowse is also a fast browse, though not as fast as TWBrowse.


Placing Browses in resources

How to place a FiveWin Browse in a DialogBox:

1. Select the custom control toolbar button (it shows a little key on it).

2. You will be prompted for the name of the custom control to use: Write TWBrowse.

3. Draw the browse area on the Dialog Box and double click on it.

4. Add the following styles at the bottom:

... | WS_TABSTOP | WS_BORDER | WS_VSCROLL | WS_HSCROLL

5. To check that everything is ok from inside the Resource WorkShop, select the PullDown menu option: "Edit as text"

The text may show an entry like this:

CONTROL "", 110, "TWBrowse", 0 | WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_VSCROLL | WS_BORDER, 4, 23, 117, 104

Instead 110 you will select the desired ID for your browse control.

6. Review the RC and DLLs we provide in the SAMPLES directory to see how we do it.


Using FiveWin indexed filters (SELECT Clause)

FiveWin Browses implement a powerful feature that allows us to retrieve just a part of a DataBase similar as a FILTER, but based on Indexes which makes it extremely fast and efficient (Clipper SET FILTER must not be used with medium-big DataBases). Advanced Clipper RDDs like Comix or SixDriver implements some features that allow similar results. Anyhow we decided to keep the SELECT clause for users of standard Clipper.

Lets see a sample of its use: Suppose you have a clients database indexed by surname. Lets suppose that you just want to review clients whose names start with L, M, N. Then you do:

REDEFINE LISTBOX oBrw FIELDS Surname, Address, ...

... SELECT Surname FOR "L" TO "N" ...

This will make the browse just show from "L" up to "N" surnames.

We called them Indexed Filters and we manage them using the LISTBOX ... FIELDS ... SELECT ... clause:

...

SELECT <cField> FOR <uValue1> [ TO <uValue2> ] ;

...

Basically what FiveWin does is a SEEK of the <uValue1> when going TOP: to find the first element to be showed. If <uValue2> is provided (it is optional) we do a SEEK of the <uValue2> when going BOTTOM: (to find the last element to be showed). If <uValue2> is not provided then we use the following index value to stop the records showed.

From <uValue1> to <uValue2> (if defined) we check that <cField> is included in that range.

In order to make this powerful clause work properly some requirements are necessary:

· The DataBase showed on the browse ( LISTBOX ... FIELDS ... ) must be indexed and the active Key must be the same as the <uValue1> we are going to seek. Please check carefully the types of the index expression and the type of the <uValue1> and <uValue2> (this one if defined).

· FiveWin does not check it <uValue1> exists. This is very important: You have to check it YOURSELF: How ? Just do a SEEK <uValue1>. If exist ( If Find() ) then proceed with the browse. There are many different possible default behaviors when the <uValue1> is not found, this is why we have decided that it is your responsibility to decide what to do if <uValue1> is not found.

FiveWin also offers a :SetFilter() method to change dynamically the current SELECTion, without having to create again the DialogBox (or the window):

:SetFilter( <cExpression>, <uValue1>, [<uValue2>] )

Sample:

The browse gets defined with:

SELECT StrZero( Page, 3 ) + StrZero( 1, 4 ) ;

FOR StrZero( nPage, 3 ) + StrZero( 1, 4 ) ;

TO StrZero( nPage, 3 ) + StrZero( 9999, 4 ) ;

And later we do:

(previously, we have changed the value of Page and nPage variables)

oBrw:SetFilter( "StrZero( Page, 3 ) + StrZero( 1, 4 )",;

StrZero( nPage, 3 ) + StrZero( 1, 4 ),;

StrZero( nPage, 3 ) + StrZero( 9999, 4 ) )

oBrw:GoTop()

oBrw:Refresh()

This clause has been extensively tested, and we guaranty it works properly. If you don't get a proper behavior it could be that you are not using it properly. Please review your code and check that all the rules that we show here are being observed in your code.

If you get strange behavior it is a clear sign that you have some other problems. We offer an extensive working sample in the IDE\SOURCE\DOC.prg. Review and you will see how to get all the power from this really useful clause.


Drawing Bitmaps inside Browses

FiveWin requires that all expressions to be shown on a browse to be of character type. The reason for this is that if you specify a number we understand it is a handle of a bitmap so there you want to show a bitmap:

See SAMPLES\FwBrow.prg:

@ 1, 1 LISTBOX oLbx FIELDS aHBitmaps[ Max( 1, Clients->Nivel ) ],;

Clients->Nombre, Clients->Direccion,;

Clients->Telefono,;

Str( Clients->Edad, 3 ) ;

HEADERS "L", "Name", "Address", "Phone", "Age" ;

FIELDSIZES 16, 240, 310, 114, 24 ;

SIZE 284, 137 OF oDlg

aHBitmaps is an array of bitmaps handles, previously loaded with LoadBitmap() or ReadBitmap() functions:

local aHBitMaps:= {eadBitmap( 0, "..\bitmaps\Level1.bmp" ),

ReadBitmap( 0, "..\bitmaps\Level2.bmp" ), ;

ReadBitmap( 0, "..\bitmaps\Level3.bmp" ), ;

ReadBitmap( 0, "..\bitmaps\Level4.bmp" ),;

ReadBitmap( 0, "..\bitmaps\Level5.bmp" ) }


Browsing arrays

// Reviewing arrays - using FiveWin TWBrowse

#include "FiveWin.ch"

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

function Main()

local oDlg, oBrw

local aSample := { "The standard", "has", "a name...",;

"CA-Clipper 5.", "Wellcome", "to", "FiveWin",;

"the CA-Clipper 5", "Windows", "Library" }

local nItem := 1

DEFINE DIALOG oDlg FROM 2, 2 TO 20, 50 TITLE "FiveWin TWBrowse Power!!!"

@ 1, 2 LISTBOX oBrw FIELDS aSample[ nItem ] ;

HEADERS "Reviewing Array" ;

FIELDSIZES 200 ;

OF oDlg ;

SIZE 100, 100 ;

ON CLICK MsgInfo( "Click" ) ;

ON RIGHT CLICK ShowPopup( oBrw, nRow, nCol )

oBrw:bGoTop = { || nItem := 1 }

oBrw:bGoBottom = { || nItem := Eval( oBrw:bLogicLen ) }

oBrw:bSkip = { | nWant, nOld | nOld := nItem, nItem += nWant,;

nItem := Max( 1, Min( nItem, Eval( oBrw:bLogicLen ) ) ),;

nItem - nOld }

oBrw:bLogicLen = {mple ) }

oBrw:cAlias = "Array"

oBrw:bKeyChar = { | nKey | MsgInfo( nKey ) }

@ 1, 20 BUTTON "&End" OF oDlg ACTION oDlg:End()

ACTIVATE DIALOG oDlg CENTERED

return nil

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

function ShowPopup( oBrw, nRow, nCol )

local oPopup

MENU oPopup POPUP

MENUITEM "&One"

MENUITEM "&Two"

ENDMENU

ACTIVATE MENU oPopup OF oBrw AT nRow, nCol

return nil

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


Browsing everything you want

The major advantage of FiveWin TWBrowse (strongly based on Clipper TBrowse model) is the capability of browsing anything you may need.

FiveWin TWBrowse is a generic browser machine capable of browsing information of any type, though as DataBase browsing is usually more common, we have added certain built-in functionality to quickly build DataBases browsers.There are certain DATAs and METHODs in a TWBrowse object, that conveniently initialized will let you browse anything:

DATAs :

· bLine: It will be used to display each browse line. It must return an array with all the columns elements to represent.

· bSkip: Used to skip certain amount of lines. This codeblock is evaluated every time the current selected line is going to change. bSkip receives a numeric parameter indicating the desired number of lines to be skipped, and it has to confirm that number returning it, or an alternative number with the real number of lines to skip:

bSkip = { | nWant, nDo | ..., nDo }

nWant represent the desired number of lines to skip. nDo will indicate the final number of lines to skip.

· bGoTop: These codeblocks are evaluated for navigating

· bGoBottom: through the represented data. Properly assigned will let you browse anything.

· bLogicLen: You must assign here the logical total length of the browse, to properly set the browse scrollbar.

As an example, lets see how we can browse an array just manipulating these DATAs:

@ 1, 2 LISTBOX oBrw FIELDS aSample[ nItem ] ;

HEADERS "Reviewing Array" ;

FIELDSIZES 200 ;

OF oDlg ;

SIZE 100, 100 ;

ON CLICK MsgInfo( "Click" )

oBrw:bGoTop = { || nItem := 1 }

oBrw:bGoBottom = { || nItem := Eval( oBrw:bLogicLen ) }

oBrw:bSkip = { | nWant, nOld | nOld := nItem, nItem += nWant,;

nItem := Max( 1, Min( nItem, Eval( oBrw:bLogicLen )),;

nItem - nOld }

oBrw:bLogicLen = { || Len( aSample ) }

oBrw:cAlias = "Array"

oBrw:bKeyChar = {| nKey | MsgInfo( nKey ) }


Basic Concepts about printing in Windows

The major difference between managing the printer in MsDos and in Windows is the fact that in Windows we manage the printer in graphical mode.

This means that we are going to manage different sizes of fonts, that we are going to manage text and drawings, that we may need to preview all that on the screen, and the most important thing: that different printers may have different resolutions, and we have to control all that.

FiveWin automatize all these processes giving you maximum power with minimum complexity. FiveWin categorizes all printing works in these different types:

· Quick printinng techniques!

· Managing the printer object

· The Report Engine


Quick Printing techniques

Besides the sophisticated FiveWin Report Engine, FiveWin offers you RAD (rapid application development) techniques to quickly prototype your printouts, with no work at all on your side!:

· Generating a full report from the current workarea:

Just call the function Report() and you will get a full paged report automatically generated from the current workarea!

· Generating an automatic report from any Browse !!!:

If you do <oBrw>:Report() where <oBrw> is a reference to your browse, FiveWin will generate a full report with the same contents of your browse. So, the easiest way to implement a report in your browse is placing a bitmap button on your DialogBox with the action <oBrw>:Report().

· Making a printer HardCopy of any window or control !!!:

If you have a Dialog and you want to obtain a printout of it, the easiest way is just doing: <oDlg>:HardCopy( <nZoom> ) where <oDlg> is your Dialog object and <nZoom> is a scale factor - a value of 3 is normally recommended to obtain natural dimensions- You can use a bitmap instead of the Dialog, or any window or control!

Combining these techniques you can very quickly prototype your first application printouts. Don't forget them!

Remember to use these techniques on the first stages of your application.


Managing the printer as an object

FiveWin manages the printer as an object, so controlling the printing process is as easy as manipulating, from an object oriented point of view,the printer object.

More:


How to create a Printer object ?

FiveWin provides a TPrinter Class to manage the printer as an object, and some specific xBase commands to easier much more that manipulation:

PRINT oPrn NAME "My Printout" PREVIEW

PAGE

...

oPrn:Say( nRow, nCol, cText, ... )

...

ENDPAGE

ENDPRINT

The PRINT command is building there a TPrinter object. From that moment on we may manipulate it directly, using all the DATA and METHODs offered by the TPrinter Class.


How to manipulate the Printer Object ?

Normally you create several pages using the commands:

PAGE

...

ENDPAGE

And from inside that section you send messages to the Printer object. The most common message used is <oPrn>:Say() :

oPrn:Say( nRow, nCol, cText, ... )

Remember that the coordinates where you are printing depend upon the specific printer resolution you may be using. In order to control this, you have to ask the printer object about its specific resolution:

· oPrn:nVertRes() is the number of pixels in vertical

· oPrn:nHorzRes() is the number of pixels in horizontal

Now, you divide those values by the number of rows and cols that you want to manage, and increase nRow, nCol according to those steps. See SAMPLES\TestPrn2.prg


How to define a font that adapts to a specific Printer Object

To create a font object that adapts its size to the specific resolution of a printer, we use as always the container clause OF :

local oPrn, oFont

PRINT oPrn

DEFINE FONT oFont NAME "Arial" SIZE 0, -10 OF oPrn

...

PAGE

...

oPrn:Say( nRow, nCol, cText, oFont, ... )

...

ENDPAGE

ENDPRINT

oFont:End()

Remember to destroy the font once you have finished printing.


Fivewin Report Engine

More:

Managing the FiveWin report engine

IMPLEMENTING TOTALS:

HEADERS & FOOTERS:

MULTILINE TITLES, HEADERS AND FOOTERS:

USING EXPRESSIONS:

REPORT DESTINATION:

USING FONTS:

CONFIGURING COLUMNS:

MULTILINE COLUMNS:

MAKING GROUPS:

SUMMARY REPORTS:

CONTROLLING THE FLOW OF THE REPORT:

UNDERSTANDING THE REPORT OBJECT:

GOING BACKWARDS:

PRINTING ARRAYS:

SHADOWS & GRIDS:

CHANGING THE ASPECT:

BITMAPS:

BOXES & LINES:

PRINTING MEMOS:

PUTTING IT ALL TOGETHER:

ALL TOGETHER AND WITH COLORS!

PRINTING FROM A .TXT FILE:

Report Classes

Report samplesThey are located at samples\report directory.


Managing the FiveWin report engine

All the reports have the following construction:

LOCAL oReport

REPORT oReport ...

COLUMN ...

COLUMN ...

END REPORT

ACTIVATE REPORT oReport ...

As you can see the basic construction is very simple. Here is the complete syntax with all the optional bells and whistles:

REPORT [ <oReport> ] ;

[ TITLE <bTitle, ...> [< LEFT|CENTER|CENTERED| RIGHT > ] ];

[ HEADER <bHead, ...> [<LEFT|CENTER|CENTERED|RIGHT> ] ];

[ FOOTER <bFoot, ...> [<LEFT|CENTER|CENTERED|RIGHT> ] ];

[ FONT <oFont, ...> ] ;

[ PEN <oPen, ...> ] ;

[ < lSum:SUMMARY > ] ;

[ < file: FILE | FILENAME | DISK > <cRptFile> ] ;

[ < resource: NAME | RESNAME | RESOURCE > <cResName> ] ;

[ < toPrint: TO PRINTER > ] ;

[ < toScreen: PREVIEW > ] ;

[ TO FILE <toFile> ] ;

[ TO DEVICE <oDevice> ] ;

[ CAPTION <cName> ]

GROUP [ <oRptGrp> ] ;

[ ON <bGroup> ] ;

[ HEADER <bHead> ] ;

[ FOOTER <bFoot> ] ;

[ FONT <uFont> ] ;

[ < lEject:EJECT > ]

COLUMN [ <oRptCol> ] ;

[ TITLE <bTitle, ...> ] ;

[ AT <nCol> ] ;

[ DATA <bData, ...> ] ;

[ SIZE <nSize> ] ;

[ PICTURE <cPicture, ...> ] ;

[ FONT <uFont> ] ;

[ < total: TOTAL > [ FOR <bTotalExpr> ] ] ;

[ < ColFmt:LEFT | CENTER | CENTERED | RIGHT > ] ;

[ < lShadow:SHADOW > ] ;

[ < lGrid:GRID > [ <nPen> ] ]

ENDREPORT

ACTIVATE REPORT <oReport> ;

[ FOR <for> ] ;

[ WHILE <while> ] ;

[ ON INIT <uInit> ] ;

[ ON END <uEnd> ] ;

[ ON POSTEND <uPostEnd> ] ;

[ ON STARTPAGE <uStartPage> ] ;

[ ON ENDPAGE <uEndPage> ] ;

[ ON POSTPAGE <uPostPage> ] ;

[ ON STARTGROUP <uStartGroup> ] ;

[ ON ENDGROUP <uEndGroup> ] ;

[ ON POSTGROUP <uPostGroup> ] ;

[ ON STARTLINE <uStartLine> ] ;

[ ON ENDLINE <uEndLine> ]

[ ON CHANGE <bChange> ]

With the command COLUMN (syntax above) you indicate all the columns that the report will have indicating the data and the title of each column. This can be very simple. For example:

COLUMN TITLE "Name" DATA Test->Name


IMPLEMENTING TOTALS:

If you want a Total on any column just add the word TOTAL in the command, for example:

COLUMN TITLE "Salary" DATA Test->Salary TOTAL


HEADERS & FOOTERS:

You can put any header and footer on the report by declaring them in the REPORT command. For example:

REPORT oReport TITLE "My First Report" ;

HEADER "This is the header" ;

FOOTER "This is the footer"

You can even specify how it will be written: left, centered or right, adding the word LEFT, RIGHT or CENTER|CENTERED. For example:

REPORT oReport TITLE "My First Report" ;

HEADER "This is the header" RIGHT ;

FOOTER "This is the footer" CENTER

Remember: by default Titles are centered and Headers and Footers are written on the left side.


MULTILINE TITLES, HEADERS AND FOOTERS:

If you want more than one line for a title just put a comma between each title. For example:

REPORT oReport ;

TITLE "My First Report", "with FiveWin"

The same happens with headers and footers.

The report engine NEVER puts a white line between the header and the title or between the title and the column titles. It is up to you to put the blank lines wherever you want them. For example, if you want to put a blank line between the header and the title, just indicate a second line on the header with nothing on it -- just an empty chain:

REPORT oReport TITLE "My Report ;

HEADER "My Header", " "


USING EXPRESSIONS:

You can put almost anything you want in your reports because you can use any expression that returns a character string, remember this is the key to do almost anything you want. For example, if you want to put the date() on the report plus the current page number, just do the following:

REPORT oReport TITLE "My Report" ,;

"date:"+DtoC(Date()) ;

FOOTER "Page Number: "+ ;

Str(oReport:nPage,3)

You can put expressions rather than character strings in almost anywhere: Titles, Headers, footers, Column titles, column data, etc...


REPORT DESTINATION:

By default, the report is sent to the printer, but you can change it when you create the report:

REPORT oReport .... ;

TO PRINTER => (The default)

REPORT oReport .... ;

PREVIEW => (To Screen)

REPORT oReport .... ;

TO FILE <cFile> => (Txt format)

When you send the report to the screen (PREVIEW), the report engine creates all the pages until you push the button Preview, and then you will immediately see the first page created.

When you create a Report you can specify a caption for it. This caption would be the title of the preview Window if you send the report to the screen, or it will be the description on the spooler if you send it to the printer. (In previous releases we used the word NAME for this.)


USING FONTS:

You can use any font you want with your reports. This is the way you use them:

First you have to define them with the command DEFINE FONT oFont ....

DEFINE FONT oFont1 NAME "ARIAL" SIZE 0,-10

DEFINE FONT oFont2 NAME "ARIAL" SIZE 0,-10 BOLD

The size (width,height) specs. use different units of measure when printed versus displayed on screen. On screen, the units are pixels, but when printed, the units are font "points". Thus, for printed text, we only use the second size specification (height) to give the point size, leaving the "width" as "0". The point size is given as a negative number, i.e. "10 point" is "-10".

Remember that point size for proportionally spaced type is different than "pitch," which is the term often used for non-proportionally spaced "typewriter" type like Courier. Point size refers to letter height, whereas pitch refers to the number of equal-spaced letters printed per inch. Regular "pica" sized typewriter type is 10 pitch - 10 letters per inch. But represented in point size, this is 12 point -- very confusing because the smaller "elite" typewriter type is 12 pitch - 12 letters per inch, which is 9 point. (With "pitch," the bigger the number, the smaller the font -- just the opposite of how "point" size works.)

Now to add to the confusion, remember that in this Report Engine, we let FiveWin know that we're working with point size instead of pixels by using negative numbers for points (and we must use points instead of pitch for equal-spaced fonts like Courier). In this case, the "-" sign isn't mathematical -- it doesn't mean (as math rules would suggest) that your point size gets smaller as the integer gets bigger. Just the reverse. The bigger the integer, the bigger the point size. If you're still confused, there's a fellow named Guttenberg on CIS who can explain it all to you.

When you create the report, you specify the fonts you want to use, separating each one with a comma.

For example:

REPORT oReport TITLE ..... ;

FONT oFont1, oFont2, oFont3

The first font in the list (oFont1) will be the standard font, so if you do not specify a font for a specific column it will use the standard font (oFont1).

If you want a column to use the second font just do the following:

COLUMN TITLE ... DATA .... FONT 2

As you can see, you indicate the ordinal number in the list of fonts defined when you create the report.

Again, you can use an expression this way:

COLUMN TITLE ... DATA ... ;

FONT iff(Test->Salary>1000,2,1)

Remember to release the fonts after the report is done.


CONFIGURING COLUMNS:

When you create the columns, you can specify a lot of behavior:

- PICTURE: As same as GETS

- SIZE: Length of the column (number of Chars)

- AT: Print at specific column (better not use it)

- FONT: Font to use (number in the list of fonts)

- TOTAL: if the column should have a total

If you specify that the column has a total, the DATA should be a number. But if not, do not worry -- the report engine does not break. The TOTAL clause can have also a FOR condition. For example:

COLUMN DATA ... TOTAL FOR Test->Name = "Peter"

LEFT|CENTER|CENTERED|RIGHT: You can also specify the way the text is going to be printed, left, center or right. By default, everything is left formated except numeric data which is right.


MULTILINE COLUMNS:

This is something you will really love: suppose you need to put another column but you do not have enough width on the paper to do it?

You could use a smaller font, but this is not the best way. The best way is to use multi lines for columns. That means that one database register can use more than one line on the report. So we can do something like this:

Name | Salary
Test->First Test ->Last | Test->Salary

This is as simple as:

COLUMN DATA Test->First, Test->Last

Just separate with a comma the data you want to be printed.

You can do the same with the column title, like this:

COLUMN DATA Test->First, Test->Last ;

TITLE "First Name" ,"Last Name"

If you put a TOTAL on that column, all the numeric data will be added. All the data will have the same picture, but I will explain later how to change this behavior.


MAKING GROUPS:

To make a group means to have a subtotal on a particular kind of data. With the report form you can make two groups. With other report generators you can make up to 9, but with FiveWin Report Engine you have no limit.

If you want the totals of the groups to be printed you must totalize at least one column.

The data, of course, should be sorted in accord with the group expression.

To make a Group just do the following:

REPORT oReport ....

COLUMN ....

COLUMN ....

GROUP ON Test->State EJECT

END REPORT

The report will totalize each column that has been created with the TOTAL clause for every State and will make a page eject when the State changes.

You can even specify a Header, a Footer and a font to use for that group (just one line on Headers and Footers):

GROUP ON Test->State ;

FOOTER "Total State:" ;

FONT 2 ;

EJECT

Remember, you can have all the groups you want.


SUMMARY REPORTS:

If you specify the clause SUMMARY when you create the report:

REPORT oReport TITLE ... SUMMARY

it will only print the information about groups. So the clause SUMMARY should only be used when there is at least one group defined.

When you use the SUMMARY clause the report engine does not put any group separator line.


CONTROLLING THE FLOW OF THE REPORT:

When you activate the report, it is possible to define FOR and WHILE conditions. For example:

ACTIVATE REPORT oReport ;

WHILE Test->State = "A" ;

FOR Test->Salary > 1000

Because the report engine can make a report even from an array, by default the WHILE condition is "!Eof()". So if you change the WHILE condition, you must take care that if you are making a report from a database it is a good practice to include in the WHILE condition the text ".and. !Eof()":

ACTIVATE REPORT oReport ;

WHILE Test->State = "AZ" .AND. !Eof() ;

FOR Test->Salary > 100000

You can even control the flow of the report in the same manner as you do with other windows.

When you activate the report you can indicate functions that will be called when the report is in a particular state:

ACTIVATE REPORT oReport ;

ON INIT ... ;

ON END .... ;

ON STARTPAGE ....;

ON ENDPAGE ... ;

ON STARTGROUP .... ;

ON ENDGROUP .... ;

ON STARTLINE ... ;

ON ENDLINE .... ;

ON CHANGE ...

The INIT function is called just one time on the first page after the column titles are printed.

The END function is called just one time on the last page after the Grand totals are printed.

The STARTPAGE is called on every start of a page. This is one of the most used because in this clause you will put bitmaps, lines, boxes, etc...

The ENDPAGE is called on every end of a page, when all the text is printed (not very useful).

The STARTGROUP is called on every start of a group and before the header of the group is printed (if there is one).

The ENDGROUP is called on every end of a group.

The STARTLINE is called on every start of a line of the report body. When STARTLINE is evaluated, the report engine is controlling if the following line will fit in the current page, and if not, it will do an Eject and start a new page. Be carefull when using STARTLINE, because if you use Multiline columns there will be at least two STARTLINES for each record processed.

The ENDLINE is called on every end of line of the body report. When ENDLINE is evaluated all the line has been printed and the current report line is been incremented.

The CHANGE is called on every "SKIP" if you are listing a database. For practical purposes, this function is called before the SKIP and not after. This is also a clause you will use a lot.

In the source code we have include a blank line on StartGroup and a sound beep when the report is finished.

IMPORTANT: Be careful when using these clauses. Remember you are inside the report flow, so you must take care of all the databases, indexes, etc.. that the report is using.


UNDERSTANDING THE REPORT OBJECT:

You can access almost any part of the report if you understand how it works and how it is designed.

The report object has a lot of data and methods that you should know and use.An object report has at least one object column, one object Line (for the title), one object device and if it has group(s), it will also have a Group object.

The objects TRColumn, TRLine and TRGroup are the basis of the report engine.

TRColumn holds all the columns of the report including its title, data, totals, etc.. (vertical object)

TRLine holds all the lines wich go across the report from left to right. You can think of them as horizontal objects. These include Titles, Header and Footers.

TRGroup holds all the information about each group defined in the report.

You can manipulate the behavior of any object modifying its data or using some of its methods.Take a look at the classes data and methods. You will be impressed about all you can do. The only limit is your imagination.

Examples:

1. Change the TITLE font of column 3 to use the second font. Also because the column is multiline, change the picture of the second line to "999,999":

LOCAL oColumn

oColumn := oReport:aColumns[3]

oColumn:bTitleFont := {|| 2} // It's a block

oColumn:aPicture[2] := "999,999"

2. Left Justify the first line of the title using font 2 and right justify the second line using font 3:

#define LINE_LEFT 1

#define LINE_RIGHT 2

LOCAL oLine

oLine := oReport:oTitle

oLine:aPad[1]:= LINE_LEFT // pad of line 1

oLine:aPad[2]:= LINE_RIGHT // pad of line 2

oLine:aFont[1]:= {|| 2} // font of line 1

oLine:aFont[2]:= {|| 3} // font of line 2

As you can see, the object TRLine also holds multiple lines. That way the DATA is mostly arrays.

3. On the footer of each group, print the current value of it and the counter of how many records have been included:

GROUP ON Test->State ;

FOOTER "Total State "+;

oReport:aGroups[1]:cValue+ ;

str(oReport:aGroups[1]:nCounter)


GOING BACKWARDS:

Just do a GO BOTTOM, change the way the Report does the skip, and change the while condition:

USE TEST NEW

GO BOTTOM

REPORT oReport ....

COLUMN ...

END REPORT

oReport:bSkip := {|| DbSkip(-1)}

ACTIVATE oReport WHILE !Bof()


PRINTING ARRAYS:

Use a static variable to hold the current array element and change the Skip block and While block.

STATIC nField

Function Main()

nField := 1

REPORT oReport ....

COLUMN ...

COLUMN ...

END REPORT

oReport:bSkip := {|| nField++}

ACTIVATE REPORT oReport ;

WHILE nField <= len(aStructure)


SHADOWS & GRIDS:

There are two clauses that you can use when you create your columns:

- SHADOW: This clause puts the background of a column in light gray.

- GRID: This clause puts two lines vertically on both sides of a column.

For example:

COLUMN TITLE ... SHADOW GRID

You can modify the type of grid, width and color. To do this you have to create the pens you need:

COLUMN TITLE ... GRID <nPen>

By default the pen used is black, solid, with a width of 1.

The creation of pens is identical as for fonts. (Consult the Norton Guide for more information about pens.) For example:

DEFINE PEN oPen WIDTH 5

REPORT oReport PEN oPen

COLUMN TITLE .... GRID 1

END REPORT

ACTIVATE REPORT


CHANGING THE ASPECT:

There is some DATA on the report objects that lets you change the aspect of the report, for example:

· nTotalLine: Is the aspect for total lines. By default it is RPT_DOUBLELINE (2)

· nGroupLine: Is the aspect for group lines. By default it is RPT_SINGLELINE (1)

· nTitleUpLine: Is the aspect for the up lines in column titles. By default it is RPT_DOUBLELINE (2)

· nTitleDnLine: Is the aspect for the down lines in column titles. By default it is RPT_DOUBLELINE (2)

· cPageTotal: Is a description for page total. By default it is ""

· cGrandTotal: Is a description for grand total. By default it is ""

And also some methods like:

· Margin(nValue,nType,nScale): This method lets you change the top, down, left and right margin of the report -- in inches or centimeters.

· Say(nCol, xText, nFont, nPad, nRow): This method lets you write the text you want on the report, indicating the column (where the column objects start), the text, the number of font to use, the number of pad(left, right, center) and the Row (by default the current row).


BITMAPS:

To put a bitmap on your report is very easy. In the STARTPAGE clause, just make a call to a function of your own which draws the bitmap via the Saybitmap method() of the class TReport. An example:

ACTIVATE REPORT oReport ;

ON STARTPAGE Mybitmap()

Function Mybitmap()

oReport:SayBitmap(.3,.3,"ICO.BMP",.5,.5)

RETURN NIL

These are the parameters of the method Saybitmap:

· nRow

· nCol

· cBitmap file (only)

· nWidth

· nHeight

· nScale

If Scale is in INCHES (1) then 1,2,4 and 5 are in inches, and if Scale is CMETERS (2) 1,2,4 and 5 are in centimeters.


BOXES & LINES:

To put a box or a line on your report is very easy. On the STARTPAGE clause, just make a call to a function of your own which draws the line or box via the box or line method() of the class TReport. An example:

ACTIVATE REPORT oReport ;

ON STARTPAGE Mybox()

Function Mybox()

oReport:Box(.1, .1, 11.1, 7.6)

RETURN NIL

These are the parameters of the BOX method:

· nRow

· nCol

· nBottom

· nRight

· nPen

· nScale

If nScale is in INCHES (1) then 1,2,3 and 4 are in inches, and if nScale is CMETERS (2) 1,2,3 and 4 are in centimeters.

The fifth parameter is the number in the list of pens stated when you created the report.

These are the parameters of the LINE method:

· nTop

· nLef

· nBottom

· nRight

· nPen

· nScale

If nScale is in INCHES (1) then 1,2,3 and 4 are in inches, and if nScale is CMETERS (2) 1,2,3 and 4 are in centimeters.

The fifth parameter is the number in the list of pens stated when you created the report.


PRINTING MEMOS:

Printing memos on reports is sometimes a difficult job in other reporting systems, but is quite easy with the FiveWin Report Engine.

Look how we do it:

1. Create a column with empty DATA, but indicating the size (width of line in chars) that you want for the memo:

COLUMN TITLE "Comments" DATA " " SIZE 50

2. Create a function to be called by the ON CHANGE clause, like this:

Function SayMemo()

LOCAL nLines, nFor

nLines := Mlcount(Test->Comment,50)/*

Since ON CHANGE has caused the line to be incremented, we need to

decrement the current line once.

*/oReport:BackLine(1)

/*Now we can start the printing. But remember: before we print anything, we have to make a call to StartLine, and also afterwards a call to EndLine. This way the program controls the page breaks.

*/

FOR nFor := 1 to nLines

oReport:StartLine()

oReport:Say(nMemoColumn , ;

MemoLine(Test->Comment,50,nFor)

oReport:EndLine()

NEXT

RETURN NIL

And that is all there is to it.


PUTTING IT ALL TOGETHER:

Just take a close look at the code for REP21.PRG.


ALL TOGETHER AND WITH COLORS!

You can change the color of each font using the SetTxtColor method.

SetTxtColor() receives two parameters. The first one indicates the nColor to use (see Colors.ch) and the second one the NUMBER of the Font in the report. For example:

oReport:SetTxtColor(CLR_HRED,1)

You can also control the color of any Pens just by indicating their colors when you create them. For example:

DEFINE PEN oPen COLOR CLR_BLUE

If you want to change the color of the horizontal pen used in titles and totals, use the method SetPenColor. For example:

oReport:SetPenColor(CLR_RED)

You can also change the color of the shadows using the method SetShdColor(nNewColor), which by default is LIGHTGRAY.


PRINTING FROM A .TXT FILE:

In Rept23.PRG we are using the memo printing technique to print a text file. This is very useful for quickly converting Clipper DOS reports to windows.

For example, if your DOS application has reports created via the R&R Code Generator or Bandit, use that DOS report's option to have each report sent to a .TXT file. Then adapt the simple code in this example to have FiveWin print the report's .TXT file. Make sure that the font specified in this code matches the font used in the creation of the report. Guess what this means....you can convert each of your existing DOS reports to windows in 20 minutes each MAX, no matter how intricate they may be!

Caveat: of course, whatever user interface screen code you have at the beginning of your DOS report .prg (for prompts/responses to specify various report options) will have to be converted to FiveWin GUI. Still quick -- after you establish a standard and adaptable format for your prompts/responses.

NOTE: When previewing this report, until you zoom out it will appear garbled due to the use of the fixed pitch Courier font. If you print it, it won't be garbled.


Report Classes

Please review Classes TReport, TRColumn, TRLine and TRGroup on the FiveWin Reference Guide section.


Report samplesThey are located at samples\report directory.

More:


REP01.PRG

A very simple report

REP02.PRG

Implementing totals

REP03.PRG

Headers and footers

REP04.PRG

Multi line on title, headers and footers

REP05.PRG

The power of expressions

REP06.PRG.

To printer, to screen and to file. And caption use

REP07.PRG

Using fonts

REP08.PRG

Configuring the columns

REP09.PRG

Multi lines on columns

REP10.PRG

Making groups

REP11.PRG

Summary reports

REP12.PRG

Controlling the flow of the report

REP13.PRG

Understanding the report object

REP14.PRG

Going backwards

REP15.PRG

Printing arrays

REP16.PRG

Shadows and grids

REP17.PRG

Changing the aspect

REP18.PRG

Bitmaps

REP19.PRG

Boxes and lines

REP20.PRG

Printing memos

REP21.PRG

All together


Mixing graphics and text

#include "FiveWin.ch"

#include "report.ch"

STATIC oReport

Function Rep18()

USE TEST INDEX TEST NEW

REPORT oReport ;

TITLE "*** Fivewin Report ***" ;

PREVIEW

COLUMN TITLE "St" DATA Test->State

COLUMN TITLE "First Name", "Last Name" ;

DATA Test->First, Test->Last

COLUMN TITLE "Street", "City" ;

DATA Test->Street, Test->City

COLUMN TITLE " Salary" ;

DATA Test->Salary ;

TOTAL

END REPORT

ACTIVATE REPORT oReport ;

ON STARTPAGE Bitmaps()

CLOSE TEST

RETURN NIL

STATIC Function Bitmaps()

oReport:SayBitmap(.3,.3, "EXIT",.5,.5)

oReport:SayBitmap(3,2, "CONFIDEN.BMP",4,4)

RETURN NIL


Previewing your print-works

You may generate an impressive preview of your printouts just specifying the clause PREVIEW when building a printer object:

PRINT oPrn NAME "My Printout" PREVIEW

...

PAGE

...

oPrn:Say( nRow, nCol, cText, ... )

...

ENDPAGE

...

ENDPRINT

This will cause the printout to be reviewed first in screen, giving the user the ability to preview and interactively select what to print or to cancel the printout work.

FiveWin uses standard Windows Metafiles files to store each of the printout pages. In order to manage those metafiles, FiveWin looks for the temporary directory on your system. Remember to set a TEMP directory on your autoexec.bat:

SET TEMP=c:\temp

FiveWin will store temporarily the metafiles files inside that directory, and will delete them once the preview is finished. All these operations are managed automatically by FiveWin.


Using the FiveWing Debugger

FiveWin offers its own Windows debugger version. In order to use the debugger just compile using /b. clipper MyApp /n/b

If you use FiveWin SAMPLES\Build.bat, you can specify a second parameter after the name of your app:

build MyApp /b

When you execute your application the FiveWin debugger will automatically appear. FiveWin debugger requires the DLL we provide called FWDBG.DLL.

Building a Windows debugger is really a very complicated task since there is no a way to 'STOP' Windows activity: Windows is constantly interacting with the user, so if we just move the mouse a lot of activity starts occurring. Even Borland has been using text mode debuggers for its Windows products (Borland C++), that gives you a good idea how difficult it is.Also, using a debugger in a event-driven and OOPS architecture is something very difficult. Anyhow we have provided it as a help to find some bugs you may be looking for.

Honestly we almost never use the debugger. Instead we use some MsgInfo() function calls showing certain values at certain application execution points. We find this much more easy to manage and it gives very good results.

Also FiveWin generates a very complete Error.log file when an error occurs. Use the info we provide there to help you find the bugs.

You may use the FiveWin debugger only in those circumstances where no other solution is found. Anyhow, we strongly recommend that you contact us if there is a problem you can't solve by yourself (instead of spending a lot of time searching and searching!)


Debugging Techniques

Based on our own experience programming in Windows with FiveWin (yes! we do use FiveWin a lot! <g>) and in the experience of our users we want to recommend to you the way to debug your applications:

1. As Clipper compiles extremely fast and blinker (we recommend blinker) is also incredible, we normally compile and link many, many times as often as needed. This is our first recommendation: Try every little new part of the program you code. You will remember and understand what should be the reasons for any incorrect behavior. Don't code large parts of your application without testing. Test regularly as much as you need.

2. Debugging an event system that has been coded with OOPS technology is almost impossible using a debugger. You will go crazy just trying to follow some easy steps. The debugger is just the last way when you are completely lost and most of the times it is not useful!

3. Use MsgInfo() to place some breakpoints semaphores where you will check some values that may confirm what you think the program is doing or managing there. 80% of the debugging we do is based on MsgInfo(). Trace values, check values.

4. FiveWin generates an Error.log file that may help you to get more information about what is happening. Review it! Maybe you will find some useful information that will help you.

5. This is the golden rule: Systematically doubt even what you think you are sure about. Bugs are always placed where we could never imagine. Bugs are logic faults, that our brain did not consider. Bugs may lose a lot of your precious time. Doubt, check everything but don't get fooled! As soon as you have the feeling there is nothing else you can do, go ahead and contact us! Quickly! Don't lose your mind!

6. A professional programmer always has incredible intuition. They do not know why, but may be sure about something. Follow your intuition. Relax, calm your mind and let your intuition come like magic. Intuition is not logic. It comes from the opposite side of the brain <g> Don't force it! Go and take a little rest. Maybe when you awake the following day you will magically find it! Yes! ZEN for Fivewin!

7. We have designed and coded FiveWin! So, for us, it is much easier to find a bug. Ask us for help! We could solve in minutes what you may need weeks! Also, it may be _our_ fault! So, don't fight with it. Just ask us for technical support!


Low Level Debugging Techniques

Besides the standard Clipper errors, the world of Windows brings us a new and terrible kind of problems: GPFs. As once a Windows programmer excellent described them: "Go and Pray Faithfully!".

GPF is the shortname for General Protection Fault. All the Clipper programmers used to build MsDos Clipper apps in protected mode have ever experienced this kind of problem. Windows works in protected mode, so when we get a GPF under Windows, we are in a very similar situation as when we got them under MsDos.

When a GPF ocurrs, Windows 3.1 shows a very uggly white modal window indicating that a GPF has ocurred and reports the name of the application that caused the error and the address inside of it where the error has been located. If the name of the application is a DLL and not our application name, it could means that our app did something wrong that finally made a DLL to crash (this is normally when experiencing any GPF at Windows USER.DLL), or that a DLL is not working properly and it is experiencing problems under a certain circunstance.

Many Clipper programmers start building their own C language functions to use from Clipper, and in the beginning it is quite normal that they generate some errors that finally manifest as GPFs. In one case or in the other, it is good to get some basics to solve a GPF problem.

Both linkers Blinker and Microsoft LINK let us generate a MAP file that describe the containts of our app. Using Blinker, you may use the following LNK sentence:

MAP A, S // Generates a MAP file when using Blinker

If you use Microsoft LINK, then you can specify a third comma separated parameter that indicates the name of the MAP file to generate:

Link /se:2000 /NOE %1,, %1, FiveWin WinApi Clipper Extend 501_520...

The second %1 tells Link.exe to generate a MAP file with the same name of our application.

Now, using that MAP file we can locate the GPF source code location. Windows 3.1 reported the GPF address directly, and Windows 95 offers a 'details' button where that address is also shown. This address is normally shown using this format: SSSS:OOOO where SSSS is the segment address and OOOO is the offset address. Windows 95 uses a 32 bits offset SSSS:0000OOOO. Just discard the leftmost 0000, so you must look for SSSS:OOOO.

Normally the address you are looking for will not exactly show at the MAP file, but instead you will need to look for a range. Look for the inmediate lower range to a given GPF address.

If you are reviewing a Blinker MAP file, then you will normally be able to locate twice the address. The first one refeers to the 'segment code' where the function that generated the GPF is located, and the second time it may be the function code itself.

On the Windows 95 GPF reporting DialogBox there is also another very usefull information "Bytes at CS:EIP:". Write down this sequence of bytes as they shown exactly the assembler source code where the GPF is beeing produced. If you have a debugger like Borland Turbo Debugger you will be able to locate that sequence of bytes, so you will find exactly the code that generates the GPF.

FiveWin includes a very usefull dummy function named __GenGPF() that does nothing except generating a GPF. This is a good test you can try to get some experience. Simply place a call to __GenGPF() in your code and you will get a sure GPF. See the address we have described here, and try to locate the address of the offending code at your MAP file. If you have successfully done this test then you should have located the following addresses:

0002:8E3D 001D0H TOOLHELP_TEXT CODE

(these figures will be different in your code) and

0002:8FC5 Res __GENGPF

TOOLHELP is the name of the C module where __GenGPF() is located. As you see, you get here agood feedback to start looking for a specific problem. If you don't get an idea why a certain GPF ocurrs even if you locate its origin, please contact us and we will try to assist you.

Another source of problems that may end as a GPF, comes from a bad use of certain Windows API services. This type of error are more difficult to locate as the GPF point normally is far away from our wrong code. Here we recommend you to use a different strategy:

Windows 3.1 provides an utility named DrWatson.exe that if a GPF occurs, will generate a LOG file where the latest Windows API missuse is reported. Many times this information is very usefull to locate the possible error origin.

Once again the best assistant to locate an error is your own experience, that is why we strongly recommend you not to fight so hard, and if you don't get sollowing the above recommendations, simply contact us and we will try to assist you.


Developing windows help file

Windows Help provides online help for users working with a Windows application. Windows Help provides a practical way to present information about your application in a format users can access easily. This topic introduces the tools you can use to develop Windows Help files and to incorporate Help in Windows applications.

Windows Help files can display information by using the following elements:

· Text in multiple fonts, sizes, and colors

· Bitmaps and metafiles with up to 16 colors

· Segmented-graphics bitmaps with embedded hot spots

· Cross-reference jumps for links to additional information

· Pop-up windows to present text and graphics

· Secondary windows to present information without the full menus and buttons of Windows Help

· Keywords to help users find the information they need

You create help files by creating topic and graphics files and a Help project file. A topic file contains the text for the help topic and contains the Help statements and macros that define the format of the text and the position of graphics in each topic.

The graphics files contain the bitmaps and metafiles you want to display in the topics. The project file contains a description of how to build the help file. You use the Help Compiler to build the final help file. Combining the topic, graphics, and project files, the compiler creates a single help file (with the filename extension .HLP) that you can open and view by using Windows Help.


Managing HLP files from your applications

SET HELP TO <cHLPFile> Sets the default HELP file of the application


Hep Management functions

Please review the functions WinHelp(), GetHelpFile(),
HelpIndex(), HelpSearch(), HelpSearch(), HelpSetTopic(), HelpTopic(),
SetHelpFile(), GetHelptTopic()


Managing DLLs - Dynamic Link libraries

More:


What is and how to use a DLL

In some aspects, you may think in a DLL (Dynamic Link Libraries) as the modern version of overlays. Though, of course, DLLs are much more powerful.

A DLL contains code (functions that you may use from your application) and also data. This is why we use them in FiveWin as a way of external storing our application resources.

The big advantages of DLLs are:

DLLs can be used by several applications at the same time (and just one DLL instance is loaded by Windows!).

DLLs are programming language independent (in those situations where DLLs have been properly designed keeping in mind that other programmers may use them!).

If you develop applications that support multiple languages: create a DLL for each language supported after translating the dialogs, strings and messages to the target language(s). Then supply the appropriate .DLL (and help file) for that language.

Due to the possibility that the DLL is used by several applications at the same time, the DLL uses the variables data from the program that is using the DLL. This is something you don't have to worry about but it is convenient that you know if sometimes you decide to write a DLL.

You may not use CA-Clipper and FiveWin to develop DLLs. Use C or C++ to develop DLLs in case you need it.

There are two ways of using a function which it is stored inside a DLL:

Linking at run-time.

Telling the linker to use it.

The xBase commands that FiveWin offers are for using DLLs at run-time. This has the advantage that you may select any DLL at run-time, but a small inconvenience is that it is not as fast as if you tell the linker to automatically link it when it is necessary.

If you use the second way, which is faster, it is essential that the DLL you are going to access exists on the computer and is accessible. If not, Windows will warn you and the application will not execute.

If you plan to develop an application which extensively uses DLLs calls it is more convenient that you develop a C module that access that DLL. See the following DLLs management xBase commands for an explanation of these two ways.


DLL Management XBase commands

Defining a external DLL function to be called at RunTime

DLL [STATIC] FUNCTION <FunName>( ;

[ <Param1> AS <Type> ] ; [ <ParamN> AS <Type> ] ) ; AS <return> [PASCAL] LIB <DllName>

FiveWin lets you declare an external DLL function to be called at RunTime by its own name! Please review samples\DllCall.prg.

<FuncName> | The name of the DLL function. Remember Clipper only uses 10 characters maximum length.
<Param1> | Name of a parameter.
 | Length in bytes
<Type>, <return> | BYTE, CHAR 1 WORD, BOOL, HANDLE, HWND, HDC 2 LONG, STRING, LPSTR, PTR 4 DOUBLE 8
<DllName> | Name of the DLL.

We recommend to develop a C language based connection functions when you are going to develop an intensively work with some DLLs. See "using Windows API".

Examples:

Calling SndPlaySound() at RunTime:

#include "FiveWin.ch"

function Main()

SndPlaySound( "tada.wav", 0 )

return

DLL FUNCTION SndPlaySound( cFile AS LPSTR, nType AS WORD ) AS BOOL ;PASCAL LIB "MMSYSTEM.DLL"

Designing the same DLL connection using C language:

#include <WinTen.h>

#include <Windows.h>

#include <MMSystem.h>

#include <ClipApi.h>

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

CLIPPER SNDPLAYSOU() // ND()

{

_retl( sndPlaySound( _parc( 1 ), _parni( 2 ) ) );

}

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

In this situation it is necessary to use a specific LIB so the linker willknow how the DLL connection must be done at RunTime. Example:

TEST.DLL // Is a commercial DLL we are going to use

IMPDEF.EXE TEST.DEF TEST.DLL // IMPDEF.EXE is a tool Microsoft and Borland provides

Now, edit TEST.DEF -which it is an ascii file- and rename the symbols with 10 characters or less with an underscore:

LESS10 ---> _LESS10

Then do:

IMPLIB.EXE TEST.LIB TEST.DEF

When linking use that .LIB !

Review our \WinApi directory C -only registered users- source code to see a lot of examples of doing this.

Warning: SndPlaySound() is already built inside FiveWin.lib. It has been used just in this example for learning purposes.


Samples

More:


DLL call.prg

// This sample shows how to make a Dynamic Linking at RunTime!

// Using Borland BWCC.DLL DLLs

#include "FiveWin.ch"

#ifndef __CLIPPER__

#define BORLAND "bwcc.dll"

#else

#define BORLAND "bwcc32.dll"

#endif

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

function Main()

BWCCMessageBox( 0, OemToAnsi( "Using Borland's BWCC DLL" ),;

OemToAnsi( "Hello World!" ), 0 )

BWCCMessageBox( 0, OemToAnsi( FWCOPYRIGHT ), FWVERSION, 2 )

SndPlaySound( "Ahhhhh.wav", 0 )

return nil

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

DLL FUNCTION BWCCMessageBox( hWnd AS WORD, cText AS LPSTR, cTitle AS LPSTR,;

nType AS WORD ) AS WORD PASCAL LIB BORLAND

DLL FUNCTION SndPlaySound( cFile AS LPSTR, nType AS WORD ) AS BOOL ;

PASCAL LIB "MMSYSTEM.DLL"

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

procedure AppSys // XBase++ requirement

return


DLLclear.prg

// Utility for removing opened DLLs in Windows

#include "FiveWin.ch"

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

function Main()

local cDllName := Space( 40 )

local hDll

if MsgGet( "DLL to remove from memory", "Name DLL:", @cDllName )

hDll = LoadLibrary( cDllName )

for n = 1 to 10

FreeLibrary( hDll )

next

endif

return//---------------------------------------------------------------------//


Managing DDE - Dynamic Data Exchange

More:


What is DDE

Dynamic data exchange (DDE) is a form of interprocess communication that uses shared memory to exchange data between applications. Applications can use DDE for one-time data transfers and for ongoing exchanges in which the applications send updates to one another as new data becomes available.

Dynamic data exchange differs from the clipboard data-transfer mechanism that is also part of the Windows operating system. One difference is that the clipboard is almost always used as a one-time response to a specific action by the user--such as choosing the Paste command from a menu. Although DDE may also be initiated by a user, it typically continues without the user's further involvement.

FiveWin implements two Classes TDDEMLServer and TDDEMLClient to easily manage a DDE Client-Server session.


DDE Commands

Defining a new DDE |  | DEFINE [ DDE | LINK ] <oDde> ; connection [ SERVICE <cService> ] ; [ TOPIC <cTopic> ] ; [ ITEM <cItem> ] ; [ ACTION <uAction> ] ; [ VALID <uEnd> ] ;
Activating the DDE |  | ACTIVATE [ DDE | LINK ] <oDde>
Deactivating the DDE |  | DEACTIVATE [ DDE | LINK ] <oDde>
Ending the connection |  | RELEASE [ DDE | LINK ] <oDde>
<oDde> | A reference to the DDE Object.
<cService> | The service which establishes the connection.
<cTopic> | The topic which establishes the connection.
<cItem> | The item which establishes the connection.
<uAction> | Action to perform when a connection is established
<uEnd> | An action to execute when the DDE is finished.


DDE Classes

Please review Classes TDDEMLServer and TDDEMLClient on the FiveWin reference guide.

Samples

More:


DDEMLSVR.prg #include "FiveWin.ch"

DDEMLSVR.prg

#include "FiveWin.ch"

extern DbUseArea, DbGoTop, DbSkip, DbGoBottom

static oWnd, oServer//----------------------------------------------------------------------//

function Main()

USE c:\FiveWin.19\samples\Customer

DEFINE WINDOW oWnd TITLE "DDEML Server"

ACTIVATE WINDOW oWnd ;

ON INIT InitServer()

oServer:End() // Destroyes the DDEML Server

return nil

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

function InitServer()

if oServer == nil

oServer = TDDEMLServer():New()

// Enable the application as a remote NetDDE server !!!

// oServer:SetNetDDE( .t. )

oServer:bOnConnect = { || oWnd:Say( 3, 0, "Connected!" ) }

oServer:bOnExecute = { | cCommand | ;MsgInfo( "Command: " + cCommand,;

"Server: Command Received" ) }

oServer:bOnRequest = { | cRequest, cTopic | ;RequestData( cRequest ) }

oServer:bOnDisconnect = { || MsgInfo( "The client has disconnected!" ) }

endif

return nil

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

Function RequestData( cRequest )

local cResult := &( cRequest ) // Clipper powerfull macros... <g>

return oServer:Return( cResult )

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


DDEMLCLI.prg

// FiveWin Class TDDEMLClient demonstration

#include "FiveWin.ch"

static oWnd, oClient

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

function Main()

local oBar, cData

DEFINE WINDOW oWnd TITLE "DDEML Client"

DEFINE BUTTONBAR oBar 3D OF oWnd

DEFINE BUTTON OF oBar ;

ACTION InitClient() ;

TOOLTIP "Connect to the Server"

DEFINE BUTTON OF oBar ;

ACTION RequestData() ;

TOOLTIP "Make a Request"

DEFINE BUTTON OF oBar ;

ACTION oClient:Execute( "Any command" ) ;

TOOLTIP "Send a command"

DEFINE BUTTON OF oBar ;

ACTION If( oClient != nil,; ( oClient:End(), oClient := nil ),) ;

TOOLTIP "Disconnect"

SET MESSAGE OF oWnd TO "FiveWin - DDEML management" NOINSET

ACTIVATE WINDOW oWnd

return nil

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

function InitClient()

if oClient == nil

oClient = TDDEMLClient():New()

// for NetDde conversations

// if oClient:NetConnect( "ANTONIO", "DdeMlSvr.exe" )

if oClient:Connect( "DDEMLSVR", "Test" ) // "Test" --> any word

MsgInfo( "Connection Established!" )

else

MsgInfo( "Cannot connect to server" )

endif

endif

return nil

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

function RequestData()

local n

for n = 1 to 20

oWnd:Say( n, 2, oClient:Request( "CUSTOMER->Last" ) )

oClient:Request( "CUSTOMER->( DbSkip() )" )

next

SysRefresh()

return nil

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


Managing MAPI - Mail Services

More:


What is MAPI?

MAPI is the brief name for Mail Application Programming Interface. MAPI is a Windows group of services specifically designed for exchanging mail.


Managing MAPI - Mail Services

Creating a MAPI mail message:

DEFINE MAIL [<oMail>] ;

[ SUBJECT <cSubject> ] ;

[ TEXT <cText> ] ;

[ TYPE <cType> ] ;

[ DATE <dDate> ] ;

[ TIME <cTime> ] ;

[ CONVERSATION <cConversation> ] ;

[ <rec: RECEIPT> ] ;

[ <user: FROM USER> ] ;

[ FILES <cFileName1> ,<cDescript1> ;

[,<cFileNameN> ,<cDescriptN> ] ] ;

[ ORIGIN <cOrigin> [,<cOriginAddress>] ] ;

[ TO <cTarget1> [,<cTargetAddress1>] ;

[,<cTargetN> [,<cTargetAddressN>] ] ]

Subject | Mail subject
Text | Mail body text
Type | Type of message
Date | Date stamp of the message
Time | Time stamp of the message
Conversation | Conversation Id
Receipt | If receipt is requested
From User | Interactivily creation of the mail message
Files | Files to attach to the message (cFileName, cDescription)
To | Recipients of the message (cName, cAddress)

Sending mail messages:

ACTIVATE MAIL <oMail> => <oMail>:Activate()

SEND MAIL <oMail> => <oMail>:Activate()


Samples

// FiveWin - Windows MAPI (mail services) support demonstration

// This is only for Windows for WorkGroups, Windows NT and Windows 95 !!!

#include "FiveWin.ch"

#include "Mail.ch"

static oWnd

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

function Main()

local oBar

DEFINE WINDOW oWnd TITLE "Using Windows MAIL Services"

DEFINE BUTTONBAR oBar _3D SIZE 33, 33 OF oWnd

DEFINE BUTTON OF oBar ACTION MsgInfo( MAPILogOn() ) ;

MESSAGE "LogOn in the mail system" TOOLTIP "LogOn"

DEFINE BUTTON OF oBar ;

ACTION ( MAPILogOff(), MsgInfo( "MAIL LogOff done!" ) ) ;

MESSAGE "LogOff from the mail system" TOOLTIP "LogOff"

DEFINE BUTTON OF oBar GROUP ;

ACTION InteractiveMessage() ;

MESSAGE "Send an interactive message" TOOLTIP "Interactive"

DEFINE BUTTON OF oBar ;

ACTION DirectMessage();

MESSAGE "Send a direct message" TOOLTIP "Direct"

DEFINE BUTTON OF oBar GROUP ACTION oWnd:End() TOOLTIP "End"

SET MESSAGE OF oWnd TO "FiveWin - Windows MAIL support" CENTERED

ACTIVATE WINDOW oWnd ;

VALID MsgYesNo( "Want to end ?" )

return nil

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

function InteractiveMessage()

local oMail

DEFINE MAIL oMail ;

SUBJECT "Testing..." ;

TEXT "This is real xBase power at your fingertips!" ;

FROM USER ;

RECEIPT

ACTIVATE MAIL oMail

MsgInfo( oMail:nRetCode )

return nil

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

function DirectMessage()

local oMail

DEFINE MAIL oMail ;

SUBJECT "FiveWin Mail-control power" ;

FILES "c:\test.doc", "test.doc";

TEXT "This is real xBase power at your fingertips!" ;

TO "ALinares", "FAX: 05909294"

ACTIVATE MAIL oMail

MsgInfo( oMail:nRetCode )

return nil

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


Managing ODBC and SQL

More:

What is ODBC?

When and Why ODBC?

What is SQL?

How do I use ODBC?

ODBC XBase commands

CLAUSES

Working Samples

Microsoft documentation


What is ODBC?

ODBC is the standard proposed by Microsoft Windows for using DataBases from any Windows application. You may think about ODBC as we think about the Clipper RDD system.

Clipper RDD system -replaceable Data drivers- is an open architecture to be used in Clipper applications. Just for Clipper.

Windows ODBC system -Open DataBase connectivity- is an open architecture to be used in ALL Windows applications.

As Clipper has an internal engine to support all RDD connections, likewise ODBC has a common engine (in ODBC.DLL) which lets all ODBC drivers connect easily, using the same way.

ODBC is supported through a little DLL -about 40 Ks- that serves as an interface between Windows applications and any kind of ODBC driver:

1. Your Windows application

→

2. Windows ODBC.DLL

→

3. Your ODBC

Driver

→

4. Your DataBase

The ODBC driver has to follow the ODBC.DLL rules, so we don't have to worry about it as we know that it will always be used in the same way. ODBC lets Windows applications use any kind of DataBases in the same way!

FiveWin encapsulates this process and offers you a powerful xBase and OOPS management:

1. Your FiveWin application

→

2. ODBC Objects easily managed through xBase

→

3. Windows ODBC.DLL

ODBC.DLL offers a lot of functions to manage different ODBC services. FiveWin manages them all with the standard Clipper DBFs management methods.

We are building a Clipper RDD to manage ODBC, so in future versions of FiveWin, managing ODBC will be as easy as:

USE "MyDataBase" VIA "ODBC"

Right now we offer a powerful ODBC class to easily manage ODBC. When our ODBC RDD is ready, then we will manage FiveWin ODBC objects through the Clipper RDD driver.

Clipper ODBC RDD coming in FiveWin 2.0!

1. Your FiveWin application

→2. Standard Clipper DBF use

→

3. ODBC Objects easily managed through XBase

→

4. Windows ODBC.DLL


When and Why ODBC?

Though ODBC is a very nice concept and, of course, some ODBC drivers work quite well, we believe from our experience and conversations with FiveWin users that ODBC it is not at all as easy and fast as CA-Clipper standard DataBase management power (especially if you use the SixDriver or Comix!).

We recommend that you keep using your CA-Clipper DBFs designs and your existing routines and applications.

There are some circumstances where using ODBC may be extremely useful. We think FiveWin ODBC capabilities are really useful by offering downsizing to companies. Imagine a company which uses DataBases that can be accessed through ODBC. You can take your CA-Clipper and FiveWin and convert those DataBases into standard CA-Clipper DBFs and indexes (managed with your RDDs). This is a good opportunity for you to gain business. Many companies are willing to downsize to PC platforms. CA-Clipper and FiveWin-ODBC may be the key!

Of course you may use ODBC if you want to or if you need to. In these circumstances remember not all ODBC drivers are as powerful as Clipper, and you will discover, possibly a big surprise, that sometimes your 'normal' Clipper processes can not be performed in ODBC!

We have not covered all the possibilities and situations in FiveWin ODBC that you may face when trying to manage ODBC drivers. However we have offered an open architecture which you may use and extend to suit your particular needs.


What is SQL?

Microsoft Windows has chosen SQL as the standard method to manage ODBC drivers. SQL is the programming system to manage ODBC architecture.

SQL means Structured Query Language, and in some aspects it is very similar to what we are used to with Clipper and xBase dialects.

There are different levels of SQL, according to SQL historic evolution. Right now we may find:

· SQL - core level

· SQL - Level 1

· SQL - Level 2

The core level is the most basic and standard system. All ODBC drivers accept most of SQL core level rules. Level1 and Level2 offer more powerful capabilities. The first thing you need to identify when using an ODBC driver is exactly at which level it operates. ODBC driver manufacturers may provide an extensive documentation and samples.

Some drivers DON'T accept all ODBC capabilities. Carefully review your ODBC driver documentation to learn its capabilities.

SQL is managed using functions and SQL commands.

SQL functions are managed in the same way as we manage Clipper functions. They are just functions.

SQL commands are strings which contains a SQL statement to be executed:Sample: "SELECT * FROM Dialog"

To execute this statement, we use it as an argument to a function call:

SQLExecDirect( ..., "SELECT * FROM ..." )

FiveWin offers an ODBC Class that automatically does all these in a very easy way.


How do I use ODBC?

First, the most important thing you have to do is to properly configure ODBC used in Windows.

ODBC drivers and Windows MUST be properly configured at the USER level to function correctly. You can not develop an ODBC application that will work unless everybody has ODBC properly installed in their computers. ODBC is not 'self-contained' like the CA-Clipper DBFs management (where you can generate your DBFs and indexes on the fly!).

ODBC requires some specific installation. Basically, Windows needs to know exactly, in advance, which DataBases are going to be used through ODBC, where they are and what drivers will they use.

There is a ODBC xBase driver, provided by Microsoft but it is not AT ALL as powerful as CA-Clipper RDDs. Keep this in mind.


ODBC XBase commands

Using a DataBase through ODBC

DEFINE ODBC <oDbc> ;

[ NAME <cName> ] ;

[ USER <cUser> ] ;

[ PASSWORD <cPassword> ] ;

[ CONNECT <cConnect> ] ;

[ FROM USER ]

Executing a SQL statement ODBC <oDbc> [ SQL | EXECUTE ] <cCommand>

<oDbc> | A variable which holds the reference to the object ODBC.
<cName> | The name of the DataBase to use.
<cUser> | The name of the user who is going to manage the DataBase.
<cPassword> | An optional password required to use the DataBase.
<cConnect> | Some ODBC drivers require a connection string, which normally includes the <cName>, <cPassword>, and other extra required information.
<cCommand> | A character string which holds the ODBC statement to execute.


CLAUSES

FROM USER

Means that we want to select interactively the

DataBase to use.


Working Samples

// FiveWin ODBC management !!!

// ODBC = Open DataBase Connectivity

#include "FiveWin.ch"

static oWnd

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

function Main()

local oBrush

// SET 3DLOOK ON

DEFINE BRUSH oBrush FILE "..\bitmaps\odbcdem.bmp"

DEFINE WINDOW oWnd FROM 1, 1 TO 20, 75 TITLE "Testing ODBC" ;

MENU BuildMenu() BRUSH oBrush

@ 2, 2 BITMAP FILE "..\bitmaps\ODBC.bmp" OF oWnd

@ 12, 2 BITMAP FILE "..\bitmaps\ODBC2.bmp" OF oWnd

ACTIVATE WINDOW oWnd

return nil

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

function BuildMenu()

local oMenu

MENU oMenu

MENUITEM "Use &ODBC" ACTION TestOdbc()

ENDMENU

return oMenu

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

function TestOdbc()

local oDbc, oDlg

local oName, cName

DEFINE ODBC oDbc CONNECT "DSN=Dialog" FROM USER

cName = oDbc:FieldGet( 1 )

DEFINE DIALOG oDlg FROM 2, 2 TO 14, 60 TITLE "ODBC Management"

@ 2, 2 SAY oDbc:FieldName( 1 ) OF oDlg

@ 2, 6 GET oName VAR cName OF oDlg COLOR "W+/RB"

@ 5, 10 BUTTON "&Next" OF oDlg ;

ACTION ( oDbc:Skip(),;

cName := oDbc:FieldGet( 1 ),;

oName:Refresh() )

ACTIVATE DIALOG oDlg

oDbc:End()

return nil

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


Microsoft documentation

Microsoft provides really extensive documentation explaining what ODBC is and how to use it.

ODBC is something quite complicated and it may require a long learning process.

Clipper DBFs management and RDDs capabilities is much easier than ODBC with almost no learning-curve. Use the power of Clipper instead.


Managing VBXs - Visual Basic Control Files

Please notice VBXs are only available for 16 bits applications.

More:

What is and how to use a VBX control ?

VBX Management XBase Coman

CLAUSES

BX Samples


What is and how to use a VBX control ?

For us a VBX control is an object we are going to use from our applications in the same manner as we use PushButtons, GETs, SAYs, Radios, CheckBoxes, etc... standard Windows objects.

When you define a VBX to be used in FiveWin through the xBase commands:

@ <nRow>, <nCol> VBX ... // Placing a VBX on a window or

REDEFINE VBX oVbx ... // Using a VBX from a DialogBox

FiveWin internally automatically builds a new Class which inherits from FiveWin Class TVbControl. This is done automatically so you don't have to care at all (let the computer work for you! <g>).

As soon as the VBX object gets initialized (Borland does this for us!) FiveWin replaces your TVbControl object with a new object based on a new class built from the information contained inside the VBX. All this complex process is done automatically. For you, it is as easy as using our beloved xBase commands.

See TVbControl FiveWin Class documentation for understand all the DATA and METHODs that all VBX controls have as standard.

When FiveWin automatically inherits the new VBX Class, it adds new DATA and METHODs according to the VBX internal information. All VBXs comes with a help file explaining theirs PROPERTIES and EVENTS, and FiveWin turns them into new DATA and METHODs!

VBX | Þ | FiveWin
Properties |  | DATA
Events |  | METHODs

For example, lets suppose you are going to use Borland's SWITCH.VBX controls:

According to that VBX manufacturer documentation, that VBX has a new property called ON which is logical and may be .t. or .f..

When that VBX switch control is clicked or Keypressed, it generates two kinds of events: "ON" and "OFF" (the VBX manufacturer informs this):

From your application you simply do:

REDEFINE VBX oVbx ID 110 OF oDlg ; // 110 is the ID you assign

ON MsgInfo( "On" ) ;

ON OFF MsgInfo( "Off" )

That oVbx object automatically will have the DATA On with logical type!

CA-Clipper extraordinary and powerful PreProcessor has allowed us to build an incredible VBX commands which are dynamic!!! and accepts any kind of ON __event__ __Action__ you may specify. Great!

So don't look inside FiveWin.ch for a ON ON ... and ON OFF clauses... They are processed dynamically letting us code any kind of Event dispatching (this is really something absolutely incredible which demonstrates the incredible power of CA-Clipper 5).

Some events, according to the VBXs manufacturer documentation, may use some parameters, which FiveWin automatically! supplies to your events dispatcher:

Suppose the VBX manufacturer specifies a "DOOROPEN" event, which automatically receives a numeric parameter nDirection:

When you use that VBX in your code you type:

REDEFINE VBX ... ON DOOROPEN TheAction( bP1 ) // TheAction( nDirection )

TheAction() may be any action you want to be performed there! And as there was just one parameter specified by the manufacturer, you only receives bP1 -block parameter 1- which has the same type as nDirection. (it is the nDirection value!!!).

bP1, bP2, bP3,... means 'block parameter 1, 2, 3, ...', which in the above sample it is of numeric type. (nDirection was numeric!).

Another sample: Suppose you are going to use a VBX which has two properties and three different kind of events:

Manufacturer Info ( Lets suppose an imaginary Phone.VBX )

Properties: |  |  | Sample
cDialNumber | Þ | The phone number to dial | "GO-FIVEWIN"
lOnLine | Þ | f the phone line is available | .t.
Events: |  |  | Parameters
Dialing | Þ | The phone control is dialing | nTries
OnLine | Þ | The call has been answered | cConectionTime
HangUp | Þ | The line is off | cHangUpTime, nCallCost

Now, we are going to use it from FiveWin:

DEFINE DIALOG oDlg RESOURCE "PhoneCall"

REDEFINE VBX oPhone ID ... OF oDlg ;

ON DIALING Dial( bP1 ) ; // nTries value !

ON ONLINE  Connect( bP1 )
;
// cConectionTime

ON HANGUP Finish( bP1, bP2 ) // cHangUpTime and

// cost of the call !

...

ACTIVATE DIALOG oDlg ;

ON INIT oPhone:cDialNumber := "GO-FIVEWIN" // lOnLine will be .f. // until it is not

// connected !

!!! This VBX will be really useful !!! <g>

Yes, FiveWin VBX support is simple and incredible! and we are sure you will become a VBXs master in just a few days!


VBX Management XBase Coman

Creating a VBX from source code (using a VBX on a window)

@ <nRow>, <nCol> VBX [<oVbx>] ;

[OF <oWnd> ] ;

[ SIZE <nWidth>, <nHeight> ] ;

[ FILE | FILENAME | DISK <cVbxFile> ] ;

[ CLASS <cVbxClass> ] ;

[ ON <cClause1> <uAction1> ;

[ ON <cClauseN> <uActionN> ] ]

[ WHEN <uWhen> ] ;

[ VALID <uValid> ] ;

[ PIXEL ] ;

[ DESIGN ] ;

Warning: Some VBXs controls need some specific initialization data, and may not work properly using them on windows. In those cases, use them only in DialogBoxes using REDEFINE VBX ...

Creating a VBX from resources (using a VBX on a dialog box)

REDEFINE VBX [<oControl>] ;

[ ID <nId> ] ;

[ OF <oDlg> ] ;

[ COLOR <nClrFore> [,<nClrBack>] ] ;

[ ON <cClause1> <uAction1> ;

[ ON <cClauseN> <uActionN> ] ]

<nRow>, <nCol> | The screen coordinates
<oVbx> | A reference to the oVbx control object
<nWidth>, <nHeight> | The dimensions of the oVbx control
<cVbxFile> | The filename of the .VBX file
<cVbxClass> | Optional VBX class name specified by the manufacturer
<cClause> | Any event name specified by the VBX manufacturer
<uAction> | Any action to execute on that event
<nId> | The oVbx control ID from inside DialogBoxes
<oDlg> | A reference to the DialogBox object container
<nClrFore>, <nClrBack> | Colors of the oVbx from DialogBoxes
<ValidFunc> | An expression to validate when the control is going to lose the focus.
<WhenFunc> | It is an expression to evaluate indicating if the control is or not enable.


CLAUSES

DESIGN | Allows the user to move and resize with the mouse
PIXEL | To use pixel coordinates instead of Text coordinates.


BX Samples

TestVbx1.prg | Sample showing CIRC3.VBX use demo from a window
TestVbx2.prg | Sample showing GRAPH.VBX use demo from a window
TestVbx3.prg | Sample showing SWITCH.VBX use demo from a window
TestBVbx.prg | Sample showing SWITCH.VBX use demo from a DialogBox


Event - Driven programmity

More:

What are event-driven application?

How many I control events?

Do I need to care about events?

Event management XBase commands.

Events management Object Oriented Management

TWindow Class

TWBrowse Class

TReport Class


What are event-driven application?

In a DOS application there is always a main loop where the application checks for the user input, normally a keystroke or mouse activity. That is the fundamental difference between DOS and Windows applications. Windows maintains one main loop and reports to the application all user activity. That is the fundamental difference between DOS and Windows applications.

Every time the user presses a key on the keyboard or does something with the mouse, Windows detects it and sends the application a message informing that an event has occurred.

Just remember, in DOS YOU have the main loop control, in Windows you don't have it, and Windows will report to you, sending you messages with information about what is happening.

In an event-driven application, we define different actions to be performed on a certain events. These actions are like 'call-backs' where program execution will jump to when a certain event is being processed.


How many I control events?

In DOS, xBase applications normally manage a very few kinds of events:

certain Keys pressed: SET KEY ... TO ... (Clipper style)

ON KEY ... ... (dBase style)

error management: ON ERROR ... (dBase style)

In Windows there are more event control situations that we will manage. This is the xBase syntax FiveWin uses:

ON <EventName> <uAction>

The <uAction> you defined is kept in a CodeBlock that will be evaluated when the <EventName> occurs.

These are some of the most typical Windows events:

ON PAINT ...

ON MOVE ...

ON RESIZE ...

ON LEFT CLICK ...

ON RIGHT CLICK ...

ON LEFT DOUBLE CLICK ....

Don't think that events are just something related to Windows activity.There are many circumstances that may generate events. For example, during report generation, there are a lot of events:

ON STARTPAGE ...

ON ENDPAGE ...

ON STARTLINE ...

ON ENDLINE ...

ON STARTGROUP ...

ON ENDGROUP ...

...

FiveWin lets you define actions to be performed when these events occur. The action you defined is what is usually called a 'call-back', because FiveWin will evaluate (call back) those actions when the events are happening.


Do I need to care about events?

Most events managed by Windows, or those managed by FiveWin (during a report generation), are managed automatically by FiveWin.

FiveWin will perform some default actions, or nothing at all, depending on the kind of the event. The normally activity is letting Windows perform its DefWindowProc() activity (Default Window Procedure). You don't have to care at all, as FiveWin will manage all these for you.

In those events where you want to take the control, you may use the:

ON <EventName> <uAction>

clause, if defined in FiveWin, for what you are doing or just directly manage the codeblocks related to those actions.


Event management XBase commands.

efining a 'call-back' action ON <EventName> <uAction>

for an event.

<EventName> | This clause depends on the event we want to control. It may be: PAINT, CLICK, RESIZE, ... (many different ones).
<uAction> | The 'call-back' action to be evaluated when that event occurs. FiveWin generates a codeblock from the <uAction> you specify:ACTIVATE WINDOW oWnd ; .. ON CLICK MsgInfo( "Hello" )Wnd:bLClicked = {|| MsgInfo( Hello" )}


Events management Object Oriented Management

Following are some of the most used events related codeblocks.You may review a certain class documentation to find the related event codeblock you are looking for.


TWindow Class

bInit | Code Block to execute on initialization
bMoved | Code Block to execute after moving the window
bLClicked | Code Block to execute when left clicking the mouse
bKeyDown | Code Block to execute when pressing a key
bPainted | Code Block to execute when painting the Window
bRClicked | Code Block to execute when right clicking the mouse
bResized | Code Block to execute after resizing a Window
bLDblClick | Code Block to execute when left double clicking the mouse
bWhen | Code Block for WHEN clause
bValid | Code Block for VALID clause
bKeyChar | Code Block to execute when pressing a no-control key
bMMoved | Code Block to execute when moving the mouse
bGotFocus | Code Block to execute when receiving the focus
bLostFocus | Code Block to execute when losing the focus


TWBrowse Class

bSkip | Like Clipper TBrowse:skipBlock. We provide a default fastDataBase skipper.
bGoBottom | Like Clipper TBrowse:goBottomBlock. We provide a default DataBase bGoBottom.
bGoTop | Like Clipper TBrowse:goTopBlock. We provide a default DataBase bGoTop.
bChange | CodeBlock to perform when moving from row to row


TReport Class

bInit | A codeblock which holds the ON INIT clause.
bEnd | A codeblock which holds the ON END clause.
bStartLine | A codeblock which holds the ON NEWLINE clause.
bEndLine | A codeblock which holds the ON ENDLINE clause.
bStartPage | A codeblock which holds the ON NEWPAGE clause.
bEndPage | A codeblock which holds the ON ENDPAGE clause.
bStartGroup | A codeblock which holds the ON NEWGROUP clause.
bEndGroup | A codeblock which holds the ON ENDGROUP clause.
bSkip | A codeblock which holds how to skip to the next report line By default { || DbSkip( 1 ) }
bChange | A codeblock which holds the ON CHANGE clause


Extending Fivewin

More:


Creating your own Clipper- Windows API new functions

Connecting Clipper to the Windows API is a very easy task. There are just two main things you should keep in mind:

· Clipper uses its own variables stack system. In order to obtain Clipper parameters from C, you have to use Clipper _par...() functions. This is the extend system of Clipper.

Also, for returning values from C to Clipper, you have to use _ret...() functions.

· Clipper uses PASCAL symbols as identifiers and 10 characters is the maximum length of its symbols. So, if you are going to use a Windows identifier with 10 or less characters, it may generate duplicated symbols.

We have renamed all Windows symbols with 10 characters length or less to _name. Check the name of the Windows API function you are going to use is inside WinTen.h and then always use the following headers order:

#include <WinTen.h>

#include <Windows.h>

#include <ClipApi.h>

We provide WinTen.h and ClipApi.h.Your C compiler will provide Windows.h. We use Borland C++ compiler:

BCC -c -ml func.c or TCC -c -ml func.c

When you register we will send you all the C source code, where you will find many, many examples to develop your own routines. Get a C compiler if you haven't got one. Using Clipper + C + Windows API is very easy!

Contact your distributor technical support service to obtain more information about enhancing FiveWin. We would like you to send us the new extensions you build for FiveWin. We will include them in the next version of FiveWin with mention of your name, of course. Thanks!


Special memory considerations

When you start building a very large Clipper and FiveWin you may follow the following recommendations:

FiveWin 1.9.2 upgrade has a set of new funtions to analize the DGroup of your application. A new ErrorSysW.prg uses these functions to analize your DG memory and help you in properly fine tune it.

Basically there are two main rules:

1. Reduce the amount of static variables used in your app. This is very easy just using a static array instead of several variables:

static one

static two

static three

change them into

static aVars := {,,}

where

#define ONE aVars[ 1 ]

#define TWO aVars[ 2 ]

etc...

This does not have sense with few statics, but it do has sense when you are managing a large amount of statics (I know of customers that use over 1000 statics). FW 192 has a new function that counts the number of statics variables your app has.

There is a powerfull utility named DGPIG (it can be found on the CA-Clipper forum) produced by Michael Devore (CauseWay) that analizes LIBs and OBJs and reports about DG consume. Clipper OBJs consume 8 bytes which it is normal and can not be fixed. But the problem normally comes from C language modules.

There are many ways why a C module can consume DG space. Normally for declaring a literal inside the C code or cause declaring a static array. This both problems can be fixed using the C clause 'far' that forces them into a different data segment:

Just keep this in mind:

The less initial DGroup your app consumes (FW 192 reports you this initial size), and the less Clipper static variables you manage, the larger Clipper stack you may have:

<----------------------------- 64 Ks -------------------------------->

DATA,_BSS (SYMP) | STACK_C | HEAP_C | CLIPPER STACK | CLIPPER STATICS

<----------- initial DG size ------->

Clipper will use the remaining DG space for its stack.

From FiveWin 1.9.2 we are allocating dynamic heap when building GETs and MultiGets from source code ( @ ..., ... GET ... ), so we have been able to successfully reduce the LNK (or DEF) file HeapSize value down to 1024 bytes and the applications are working successfully. This was not possible before as Gets and MultiGets used that area for internal working. Doing this HeapSize reduction you will get an extra 7,5 Ks for your Clipper stack!


FiveWin Architecture

If you have some experience with Object Oriented Programming (OOPS), or if you just are starting out, we are sure you will be delighted to know about the OOPS structure that FiveWin implements.

FiveWin's OOPS implementation is done on four basic levels:

1. xBase Commands

2. Classes and Objects

3. Functions and Data Structures

4. The Windows API

xBase commands are the highest level of abstraction, that is, it is the level at which you don't care about how things work and you only care about functionality, that is "to make it work".

xBase commands originally came from dBase, and they have been evolving towards a standard named "xBase". These commands are built over Objects. These Objects, and their classes are the second level of abstraction.

To use Classes and Objects it is necessary that you have some OOPS skills. FiveWin uses our library Objects to use the OOPS capability of CA-Clipper. You can contact us to get the latest commercial release of Objects, at a very low price, which includes all the documentation, examples and source code so you will be able to utilize the incredible

world of OOPS technology.

Objects are also based on functions (methods) and data. This is the next level of abstraction. You may realize as we progress through this document that the complexity grows and there are more details to understand.

Finally most of the functions we use are based on the Windows API.

Maximum productivity is reached quickly at the xBase command level. As you move down towards Windows API your power and possibilities are greater but obviously your productivity decreases. As application programers you should try to be at a intermediate level: a balance between productivity and power.

In spite of the low popularity achieved by dBase IV, that version did a big advance to consolidate the commands for creating and managing Objects although it did not offer OOPS.

So in xBase the standard is established that for creating an Object we to use the command:

DEFINE <ObjectClass> <ObjectName> [ ADDITIONAL CLAUSES ]

Note that if we use that command for create any Object, in some way we are using a generic building 'message'. This is why we recommend implementing that syntax for creating new Objects.

To activate any Object, we use:

ACTIVATE <ObjectClass> <ObjectName>

Finally, although this is not always necessary in Clipper, to destroy an Object we use the command:

RELEASE <ObjectClass> <ObjectName>

These commands get processed in their correspondents messages sent to the Object we are managing. So:

DEFINE WINDOW oWnd ==> Get transformed in ==> oWnd := TWindow():New( ... )

The use of these commands let us use a unique and common syntax for all the Objects. You may think that this is one of the targets of OOPS: We must concentrate in our goal and not in a particular implementation, that means, we should use a unique interface.

As FiveWin includes the latest version of Objects, you may use it to build new classes from the Classes that FiveWin offers you. Review the FiveWin Classes hierarchy and inspect the design and the code of its classes to understand how you should use the power of OOPS inheritance.

In FiveWin we have implemented for the first time a mixed system for developing Object Oriented environments. The system we have developed lets you use the power of OOPS and also the extensibility offered by 'pointers', in Clipper named 'CodeBlocks'.

There is certain international discussions between these two approaches. There is no an agreement about what is the optimum system. This is why we have decided to build a mixed system which uses both technologies.

When in a program we need to modify a behavior temporarily, as a example, defining a behavior for an event, we use the system based on pointers, that is, based on CodeBlocks. The reason for this is that we may suppose that behavior will not be necessary again in the future, so there is no need for building a new Class.

When we do:

ACTIVATE WINDOW oWnd ON PAINT ...

We are modifying the behavior for that window when it receives the PAINT event. This system is based on CodeBlocks. It is logical because that behavior will not be reused in the future.

But, if we were building a system that it is going to be reused in the future, then it has all sense to build a new class: this is the traditional OOPS way.

So, at FiveWin's TMsgBar Class, which is a class that will be used frequently in other programs, we inherit a new Class form TWindow and we redefine the method PAINT.

We are convinced that a good OOPS architecture should use this two building models. As you get more OOPS experience you will understand our point of view.

OOPS is marvelous, but still there are some aspects that should evolve. The construction of this mixed model may be a good way for discovering new possibilities.

More:

Introduction

What is an Object?

What is a Class?

Three main rules of an OOPS system


Introduction

We say a language system is an OOPS system when it has the following three rules:

· Encapsulation

· Polimorphism

· Inheritance

Using CA-Clipper with OBJECTS.LIB we get these three rules, so from that moment we may say :

CA-Clipper with Objects.LIB is a true Object Oriented Programming System!


What is an Object?

From the moment a human is born, they start recognizing and classifying the world around. Our brain has the automatic mechanisms to organize our world into Classes.

An Object is a collection of Data that has some typical behaviors which differentiate it from other kinds of Objects.

Object: Data + Behaviors Þ Data + Methods

Data: What the Object HAS.

Behaviors: What the Object DOES.

Example: What is a chair ? Even a child will tell us:

A chair has (DATA) :

· four legs

· a certain color

· some dimensions

· some weight

· a surface to sit on

· etc...

A chair's Behaviors (METHODS) :

· Can be built

· Can be moved from one place to another

· Supports someone if he/she sits on it

· Can be destroyed

· etc...

In these behaviors we see what the chair DOES and what can be DONE TO the chair:

The chair does:

· Supports someone if he/she sits on it

Someone may destroy the chair Þ Something is done to the chair.

The actions that get DONE TO an Object are EVENTS.

Data: What the Object HAS.

Behaviors: What the Object DOES.

Events: What is DONE to the Object.

Now lets see how we take those concepts into programming languages:

What is a Window ?A Window is an Object that HAS:

· Coordinates on the screen.

· A caption

· Some controls on its surface

· A color

· etc...

A Window DOES:

· Resize

· Iconize

· Change its position

· etc...

Some EVENTS may happen to a Window:

· The mouse Clicks on it

· The user presses a key

· The Window gets resized

· etc...

How can we get a certain action from an Object ?

Send it a Message!

oWindow:Message( params,... )

A message usually has the same name of the Method:

oWindow:Refresh() ---> Will execute ---> METHOD Refresh() CLASS TWindow


What is a Class?

A Class is a group of rules which controls how the Object gets created and what the behaviors of those Objects are.

A Class is something abstract: A collection of immaterial rules.

An Object is something real: It is a collection of Data. An Object is something material.

I have a chair. I can touch it. I can use it. The chair exists!

I speak about 'chairs' with someone. I don't mind what chairs. It is a concept that exists in everybodys mind. It is an abstraction of the material world!

In computing, a Class is a bunch of code, rules for creating and managing Objects.

In computing, an Object is a bunch of Data, real information being managed according to its Class rules!

How do we create a Class with Clipper ?

CLASS TWindow

DATA nTop, nLeft, nBottom, nRight

METHOD New() CONSTRUCTOR

METHOD Display()

ENDCLASS

That is the header declaration. We can see the Data that a Window Object will have: nTop, nLeft, nBottom, nRight and the behaviors a Window may perform: New() and Display()

Typically the New() behavior is called a 'CONSTRUCTOR' method as it is the way to build a new Object!

When in our code we do:

TWindow():New( 3, 3, 20, 40 )

We are creating an Object! That Object is a special kind of ARRAY in Clipper which has some specific Data!

That Data can have different values from one Object to another, but it will always be the same kind of Data.


Three main rules of an OOPS system

More:


Encapsulation

An Object is an inseparable unit of Data and Methods.

Both the Data and the Behaviors of a Window ARE the Window! We can not separate its Data from its Behaviors.

Different Data may cause modified Behaviors.

Behaviors may change the Data.

Data and Behaviors both depend on each other.


Polimorphism

The same message sent to Objects of different Classes, invokes different methods.

Suppose we have a ball and a glass. Then I take a hammer and I hit them:

My message --> HammerHit

Object Ball --> start jumping from one place into another.

Object Glass --> Gets destroyed into a lot of small pieces.

Now I have a TReport() Object and a TLabel() Object:

I send them the message :Print()

oReport:Print()

oLabel:Print()

I get different results on my printer!


Inheritance

We may create new Classes from the ones we already have! We say we 'inherit' new Classes from the previous ones.

In those Classes we use what we already have, but we may:

· Modify some behaviors!

· Add some new Data!

Using Inheriting Classes we build a Class Hierarchy!

In Clipper we do:

CLASS TDialog FROM TWindow

...

ENDCLASS

TDialog Objects have all the functionality of a TWindow Object but we add some new Data and we modify some behaviors!


FiveWin and Windows API relationship

More:

Introduction

Windows API messages structure

Object Oriented messages structure

Windows API/ FiveWin OOPS elements & messages equivalence


Introduction

Programming in Windows is a very difficult task. Windows is completely different from DOS and it has so many new features that it is virtually impossible for any programmer to remember them all.

For someone new to Graphical User Interfaces, the learning curve of Windows is about two years, just to manage the basic tasks. Previous C language programming is also required, which means add one more year C language training.

The traditional Windows programming way is clearly represented by Charles Petzold 'Programming in Windows' book. The Petzold's way implies using C language and the Windows SDK, the Software Development Kit provided by Microsoft.

With the advantage of Object Oriented technology, mainly based on C++, another way of developing Windows applications appeared which is clearly represented by Paul Dilascia -Windows++ book, Andrew Schulman series, Addison Wesley ISBN 0-201-60891-X-. The Dilascia's way implies using C++ language and it goes through a process of completely redesigning the Windows paradigm, converting it into a real Object Oriented environment.

Thanks to the internal Object Oriented architecture of Clipper 5 and to the OOPS extensions provided by our OBJECTS.lib library, included with FiveWin, we have developed a powerful approach to programming in Windows based on Paul Dilascia's main ideologies.

In this chapter we are going to take a look at the design of the Object Oriented architecture of FiveWin, the connection between the Windows API and the Object Oriented Clipper kernel, so you will clearly understand all the processes that are involved and how you can easily create new Classes connecting with the Windows API.


Windows API messages structure

If you review the examples provided in the Petzold book, you will realize all Windows applications have the same structure:

· Creating the application main window

· Start running the main get-message loop

· Taking decisions based on received messages

Almost all that we see in a Windows environment is a window. The PushButtons, the Scrollbars, the CheckBoxes, the Dialogs, etc... are all windows.

Windows sends messages to all windows informing them about what is happening and about what every window has to do. That is why Windows API requires the programmer to provide a window procedure for every window which will be called by Windows in order to give us the messages.

In all Windows applications there must be a typical defined window function:

long WINAPI WndProc( HWND hWnd, WORD wMessage, WORD wParam, LONG lParam )

That is the function Windows API uses to sends messages to our defined window. Let's review those parameters:

hWnd | The Window API handle of our window. Windows identifies every window using a 'handle': a numeric value Windows API internally generates. This value must NOT be manipulated, it is a 'read-only' value.
wMessage | A numeric value that identifies any of the Windows API different messages. All these different messages values are provided in a header file provided by Microsoft called Windows.h. FiveWin has its own WinApi.ch which includes the most used messages identifiers values. If you need to know about them, please review Windows.h supplied by Microsoft or Borland or any other Windows tools manufacturer.
wParam | A numeric value, a 'WORD' is a number of two bytes so it is in the range 0-216 which is used to provide the window function with some parameter value. This parameter may be many different things according to the sent message.
lParam | A numeric value, a 'LONG' is a number of four bytes so it is in the range 0-232 which is used to provide the window function with some extra parameter value. This parameter may be many different things according to the sent message.

The window function typically performs a C switch statement, a Clipper DO CASE... ENDCASE statement and performs different actions according to the message received and its parameters, provided by Windows API.

In all Petzold examples we will find C code like this:

switch( wMsg )

{

case WM_PAINT:

...

return 0;

case WM_COMMAND:

...

return ...;

...

default:

return DefWindowProc( hWnd, wMsg, wParam, lParam );

}

Windows provides a mechanism for processing unattended messages, that is default behaviors to be performed in case we don't care about all sent messages. That is why all window functions have a default call at the bottom of them to the Windows API function DefWindowProc( ... ) Default window procedure provided by Windows API.

Our window tells Windows API what to do according to the different values the window function returns. Typically there are these possibilities:

· return 0 | Means we have performed an action and we don't wan t Windows to do anything.
· return non-zero | In some cases Windows API requires some values.
· If we want | We call DefWindowProc( ... ) and returns standard behavior its value to Windows API.

This process is the main conversation system between Windows API and our defined windows. In this process we have to connect to the Clipper Object Oriented kernel in order to convert it into an Object Oriented process.


Object Oriented messages structure

Microsoft Windows it is NOT a true Object Oriented environment. The main reason for this is because it has been written using a non-true Object Oriented language, C language. C was used instead of C++ because at that time it was not available.

You may read in many places that Windows is Object Oriented. This is not true. In order to be Object Oriented is should offer the three main rules of an Object Oriented environment: Encapsulation, Polymorphism and Inheritance.

Windows should be Object Oriented and this would greatly help programmers to write Windows applications. This is why Borland, Microsoft, CA and other manufacturers have developed C++ classes libraries to convert Windows into a true Object Oriented environment.

The problem with this latest approach is that there is still no standard. If you review Microsoft, Borland and CA Class hierarchies you will find many differences. These hierarchies are extremely large and most of the time all of their features are not required in standard Windows business applications.

Windows provides a very primitive way of simulating OOPS, it is called 'SubClassing', not in the Object Oriented sense, but in a simple way of changing a windows procedure by another.

In order to make Windows a OOPS environment, it is required that all created windows and controls are automatically 'SubClassed', that is, we change the standard Windows API behavior mechanisms for the OOPS mechanisms provided by an OOP language, like C++, Clipper 5 or any other language with real OOPS capabilities.

Microsoft MFC, Borland OWL, CA CommonView and Clipper-FiveWin have been built using the same construction rules. The same construction processes are in all those products. FiveWin offers the simplest and fastest Class hierarchy structure. We have developed it in that way to get the best performance and size results. When you are in the OOPS arena you run the risk of starting to create Classes without a strong reason and you then run into the danger of huge performance decrease.

The process of converting Windows into a real OOPS environment has to be taken in two steps:

· Automatically SubClassing all windows and controls as soon as they are created. That allows us to change standard Windows behaviors.

· Designing a base general events processing mechanism to convert Windows messages into OOPS-language messages in order to take advantage of polymorphism and code reusability.

Thanks to OOPS inheritance it is possible to create a base TWindow Class which knows how to process most of all Windows API messages, and then we may inherit new Classes from it which redefine Methods and easily let us change the desired behaviors.

In FiveWin, the 'SubClassing' is done automatically through the TWindow Methods :Link() -to perform the SubClass process- and :UnLink() to restore the original procedures before the window gets destroyed. Those processes are quite sophisticated. Don't modify them.

FiveWin changes all the standard windows procedures to a single one which just gets the Clipper Object from the window handle and then automatically calls :HandleEvent() method. So :HandleEvent() receives all Windows API messages, and automatically calls the appropriate Object Method.


Windows API/ FiveWin OOPS elements & messages equivalence

Windows API | FiveWin OOPS engine
WindowProc(HWND hWnd, | oWnd:HandleEvent(wMessage, ...)
Handle hWnd | Object oWnd (oWnd:hWnd also)
Numeric WM_MESSAGE | OOPS Message oWnd:Message(...)

Returned values to Windows API

zero 0 - Message already processed

Non zero - Message already processed and Windows API required value returned

Default Windows API behavior required

return DefWindowProc( ... ) the Method just return nil


Developing Business OOPS - based applications

Based on the fact that FiveWin integrates its own Object Oriented Engine, it gives you the freedom to create all the new classes you may need so you have the real capability to create truly OOP based applications.

The main advantadge of coding using OOP is that our applications increase very much in modularity, so they are better structured and you will be able to code much more keeping a much better and simpler organization.

How can you properly code in OOP ? The key for it is to be able to recognize 'objects' in your code. And only through practise you will be able to easily recognize those objects. Once you start recognizing those objects, your code will be turning more and more OOP.

How can you recognize an Object ? Look at the variables you are using. If some variables are clearly related to different aspects of the 'same', there is a high probability that there is an object there:

local cLastName, cAddress, nAge

Now, you realize they all belong to a customer, so you create a new TCustomer Class:

CLASS TCustomer

DATA cLastName, cAddress, nAge

...

ENDCLASS

So, your code changes into:

local oCustomer := TCustomer():New()

And you will do:

oCustomer:cLastName = ...

oCustomer:cAddress = ...

oCustomer:nAge = ...

You have recognized an object, and your code is simpler now.

Now, you will be able to recognize several actions that are performed on TCustomers objects. Those different actions may become METHODs:

 |  | CLASS TCustomer
 |  | DATA cLastName, cAddress, nAge
function NewCustomer() | Þ | METHOD New()
function EditCustomer() | Þ | METHOD Edit()
function DelCustomer() | Þ | METHOD Del()


IntraNet/InterNet applications development using Clipper & FiveWin


Introduction

FiveWin powerfull Class TSocket implementation lets you build robust and powerfull IntraNet/InterNet databased applications.

FiveWin Internet foundation offers an easy and object oriented WinSock.dll TCP/IP management, and direct control over Microsoft 32 bits WinINet.dll. Microsoft 32 bits WinINet.dll is a high level Internet services DLL.

No extra software is required (as WebSite, Windows NT IIS, Personal WEB server or similar), so FiveWin turns itself into one of the most powerfull tools to develop IntraNet/InterNet databased applications.

API support

WINAPI\WinSock.c

WINAPI\WinINet.prg

More:


Internet related Classes

Please review Classes Class TSocket, TwebServer, Tinternet, TFTP,

TFTPFile, TFTPClient, TFTPServer, TSMTP, TPop3, Tproxy.


Samples

SAMPLES\\SockServ | Sockets server client/server sample
SAMPLES\\ProxOut | proxy outgoing sample
SAMPLES\\FiveGen | A databased-dictionary application with automatic WEB mgement
SAMPLES\\ProxIn | proxy incomming sample
SAMPLES\\TestSmtp | sending Internet email + files sample
SAMPLES\\GALLERY\ICopyFiles FTP | sending and receiving files sample


FiveWin InterNet software layers

The following picture illustrates the FiveWin Internet foundation layers:

FiveWin Classes

TInternet, TFTP, TFTPFile | FiveWin Class TWebServer

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

Microsoft WinINet.dll | FiveWin Class TSocket

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

Berkeley University WinSock.dll

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

Hardware

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

The bottom software layer is WinSock.dll, a DLL that comes with Microsoft that originally was developed by Berkeley University (the famous sockets!). FiveWin implements a direct connection to this DLL (WINAPI\WinSock.c), so you may directly use all its functions.

On top this DLL Microsoft builds the 32 bits WinINet.dll, a high level Internet layer wich is very usefull to manage FTP services. FiveWin is managing this 32 bits DLL thanks to our own 16-32 bits automatic thunk system, used everytime you manage FiveWin DLL32 commands (DLL.CH). In fact all the WinINet.dll support has been built using FiveWin high level DLL32 commands (SOURCE\WINAPI\WinINet.prg).

On top of the WinINet.dll layer, FiveWin implements three classes that let you easily manage WinINet.dll in an object oriented way: Class TInternet, TFTP and TFTPFile. These classes simplify so much the WinINet.dll management. Class TFTPFile lets you use remote FTP files as if they were files on your own computer ( FOpen(), FWrite(), etc...). There is a nice sample SAMPLES\GALLERY\ICOPYFIL that shows how to send and receive FTP files directly from your FiveWin app without using any Internet extra software.

On top of the WinSock.dll, FiveWin implements a powerfull object oriented Class TSocket, which makes so easy to have full control of WinSock power sockets. With this Class you may solve whatever Internet need you may have.

Using Class TSocket we have implemented Class TWebServer, a complete WEB pages server totally built-in inside your FiveWin application. Your applications may transmit WEB pages that are visible all over Internet.

The real power of this design is based on the FiveWin dynamic HTML own foundation. Before an object TWebServer sends WEB pages on the Internet, FiveWin mixes standard HTML codes with your own Clipper code requires. Simply place any Clipper expression between << >> and those expressions will be expanded in your HTML files. This means live access to your databases and remote management of your application. Microsoft is trying to implement now a solid dynamic HTML standard. You already have all this power.

FiveWin Class TWebServer transparently manages HTTP cookies, queries, mimes extensions and so on. Finally, Class TWebServer recognizes Proxy requires, so not only sends HTML files through the Internet but you may use it to let all Intranet users access the Internet world through it. Companies are very aware of Internet security risks so they don't want to let all employees to directly access the Internet, this is why they implement 'firewalls'. The 'firewall' concept requires a Proxy server that really access the Internet. FiveWin Class TWebServer offers a fully configurable Proxy server, and all this built in in your own FiveWin application.


FiveWin WEB server an Proxy Server

#include "FiveWin.ch"

function Main()

local oWnd, oBar, oWebServer

DEFINE WINDOW oWnd TITLE "Web Server"

DEFINE BUTTONBAR oBar OF oWnd 3D

DEFINE BUTTON OF oBar ;

ACTION ( oWebServer := TWebServer():New( 81 ),;

oWebServer:Activate(), oWebServer:Explore() )

ACTIVATE WINDOW oWnd

return nil


FiveWin dinamic HTML own implementation

To get the best results from FiveWin Class TWebServer and dynamic HTML generation a mixure of JavaScript (or VBScript), standard HTML and Clipper code is required.

JavaScript is a very easy to learn language. It behaves like a mixture between C and Clipper. Normally you may not need more than two days to really master it. (I learned it myself on a weekend! <g>)

Get yourself familiar with HTML code. HTML is such an easy language that you will be surprised how fast you may get it. basically there are two main operations you will be dealing with: GET and POST.

GET means the client is requiring some page. POST means the user filled some controls info (GETs, radios, etc...) and he is sending it to you. Have a look at AMPLES\FIVEGEN to see how far we can go just easily mixing these concepts.

FiveWin Class TWebServer automatically define some private variables that will be in scope for you to solve some information comming from the Internet HTTP protocol:

· When a page is requested as follows:

<filename.html>?<parameters>

FiveWin declares a 'parameters' variable that holds the <parameter> expression. Sometimes, scripting languages use Escape() function to turns high character codes into lower ones. FiveWin implements UnEscape() function to change back the effect of Escape().

· When a cookie has been defined on the client (see SAMPLES\FIVEGEN to see how to manipulate cookies with JavaScript), FiveWin defines a 'Cookie' variable that holds the cookie value. A cookie is just a string variables that hold some client defines values.

· When the user has completed some controls requested info and has submited it to you, FiveWin declares a 'Query' variable that holds the original user query values.

You will become familiar to these concepts once you start managing them just a little. You will be surprised how far you can get using your loved Clipper and developing Internet applications using FiveWin.


What is FiveWin ?

FiveWin is a library for Clipper 5 which you use in exactly the same waythat you have been using other third party libraries. The main difference is that FiveWin lets you build executables (EXEs) that run in Microsoft Windows as REAL Windows Programs. You have all the power of Windows and it's environment at your fingertips!

You don't have to know a word of Windows or its complicated programming system. FiveWin controls everything letting you use your familiar Clipper syntax in an easy and comfortable way.

The only tool you need is a linker that is capable of producing Windows executables. These include Microsoft's LINK.EXE linker, version 5.1 or greater, Optlink, or Blinker 3.x. Other "DOS only" linkers, such as RTLink, Blinker 2.x, Plink, and CauseWay, do not have the ability to create Windows executables and are, therefore, not useable.

If you prefer to use Microsoft's linker, you can get it with almost any of their language products like Microsoft C. The IBM OS/2 operating system also includes this linker.

You should not use Borland's TLINK.EXE, as it is not totally compatible with the Microsoft linking system.

Our preference is Blinker 3.x

While the linker is the only Windows tool that you must have, it is highly recommended that obtain a copy of the Borland Resource WorkShop. Visually designing and creating dialogs and Windows etc. in a resource editor is much more productive than hand coding them, but it is not required.


Compiling and Linking

More:

Compiling with Clipper 5

Linking with Ms-Link or Blinker

Your first applications

FiveWin samples guide 1

FiveWin samples guide 2


Compiling with Clipper 5

To compile your FiveWin applications, just use your Clipper commands as usual:

CLIPPER Test /n/w (This assumes that your FiveWin .CH files are in the path pointed to by your SET INCLUDE environment variable. If not, use CLIPPER Test /n/w/i..

Virtuall all FiveWin applications need to specify at least:

#include "FiveWin.ch"

at the top of your program (.prg) file, to extend Clipper syntax to be able to use Windows capabilities.


Linking with Ms-Link or Blinker

We provide the following three LIBs:

FiveWin.lib, WinApi.lib, Objects.lib, 501_520.lib

501_502 is ONLY needed if you are using Microsoft LINK.

To produce your EXEs with FiveWin you need a Windows linker. FiveWin is fully compatible with:

Microsoft LINK.EXE version 5.3 and over. To use version 5.1 you have to use a tool we provide, called ExeType.exe to change the Windows version inside the EXE header. This utility can be found in the FiveWindirectory

Microsoft Link Syntax:

Link /se:700 /NOE <YourApp>,,nul, FiveWin WinApi Clipper 501_520,

If you use LINK 5.1, after the link run:

ExeType YourApp.exe 3.1

Blinker 3.0:

Blinker fi YourApp @FiveWin.lnk (you will probably want to edit this file to point to your library directories)

See FiveWin.def and FiveWin.lnk for FiveWin application special requirements.


Your first applications

More:


Start building and testing these samples

TUTOR01.PRG | Typical Welcome message, from Windows!
TUTOR02.PRG TUTOR03.PRG TUTOR04.PRG TUTOR05.PRG TUTOR06.PRG TUTOR07.PRG TUTOR08.PRG FWBORL.PRG FWBROW.PRG | Our first Window in Windows !!! Our first Window,now with Control events examples and with a message bar We are going to build a PullDown menu and we are going to assign it This is the same exercise we have done at Tutor04, but now In this exercise we are going to build Dialog Boxes directly from More work on previous Tutor06 First work with browses This sample shows how to create a simple Database Management. This sample shows how to create a typical Database Management.


FiveWin samples guide 1

We do recommend learning FiveWin through samples. Try them, modify them, feel free to use any part of them you may need.

3DOBJ.PRG

ACHOICE.PRG

ADIR.PRG

ALASKA.PRG

ALERT.PRG

ATEST.PRG

ATREE.PRG

Polipoligon sample

Using ListBoxes to perform simple selections

Small test just checking some current arrays functions from

inside Windows

Our first Window in Windows !!!

FiveWin Clipper Alert replacement

Just testing some arrays dimensioning under Windows

Using FiveWin built-in trees

AUTOLAY.PRG

BARSETUP.PRG

BIGFOLD.PRG

BMPTEXT.PRG

BTNSETUP.PRG

CALENDAR.PRG

CARET.PRG

CDROM.PRG

CLOSEDLL.PRG

COMBOS.PRG

COMPILE.PRG

COPYFILE.PRG

COREL.PRG

CUSTOMER.PRG

DBCTEST.PRG

DBF01.PRG

DBF02.PRG

DBF2RC.PRG

DBFBUILD.PRG

DBFW.PRG

DDECLIEN.PRG

DDEMLCLI.PRG

DDEMLSVR.PRG

DDESERVE.PRG

DEVCAPS.PRG

DLGTEST.PRG

DLLCALL.PRG

DLLCLEAR.PRG

EMAIL.PRG

ENDAPP.PRG

FILEBROW.PRG

FIVEDEMO.PRG

FIVEDIT.PRG

FIVEGURU.PRG

FIVETEST.PRG

FTPDIR.PRG

FTPSERV.PRG FWBORL.PRG. FWBROW.PRG

FWBROW2.PRG

FWFRAME.PRG

FWREPORT.PRG.

FWRES.PRG

GENFOLD.PRG

GENREP.PRG

GETDIR.PRG

IDXBUILD.PRG

INKEY.PRG

INSPTEST.PRG

INSTALL.PRG

KEYBSIM.PRG

LABEL.PRG

LABEL2.PRG

LBXDRAW.PRG

LEDDISP.PRG

LINES.PRG

LOLO.PRG

LONGNAM2.PRG

LONGNAME.

MDIMEMO.e

MEMORY.PRG

MSGDATE.PRG

MSSQL.PRG

FiveWin RC from DBF generator Use it for quickly

developing Dialogs

Programa: ButtonBar setup sample

testing a many pages folder

Placing text on top of a bitmap

ButtonBar Drag&Drop setup sample

Program: CALENDAR.PRG

This sample shows how to connect to CA-Ret using DDE.

Accessing Windows 32 bits API from FiveWin

Utility for unloading a DLL previously opened from another app

Showing the use of different styles of ComboBoxes controls

This sample shows how to compile an aplication from FiveWin

Interface.

Using system AVIs

Using CorelDraw to generate printing templates!!!

Some MDI application testing

Basic MDI application with reporting examples ä

FiveWin - DataBase Objects Tutorial - 01

FiveWin - Managing Drag&Drop with browses !!!

DBF to .RC generator. Quickly create Dialogs from .DBFs

A DBF DataBase builder written with FiveWin

Shows how to change from Oem to Ansi and viceversa

Testing DDE Client and DDE server capabilities with FiveWin

FiveWin Class TDDEMLClient demonstration

FiveWin DDEML Class TDDEMLServer demonstration

Using FiveWin as a DDE Server !!!

Testing DeviceCapabilities()

Massive DialogBox use test

This sample shows how to make a Dynamic Linking at RunTime!

Utility for removing opened DLLs in Windows

A sample Email program written by a FiveWin user [1]

Sample showing how to activate and to finish an external

application

Very simple file browser in FiveWin

"Control center" demo for FiveWin's samples. [1]

FiveWin own source code editor - Color Syntax highlighting

This sample shows how to build FiveWin aplications in visual Mode.

Cross-platform sample between FiveWin, FiveOS2 and FiveDos

Testing the FiveWin new Internet Classes

FiveWin Class TFtpServer demo

This sample shows how to create a simple Database Management.

Quick Browse sample

This sample shows how to create a tipical Database Management

Little sample showing the use of different DialogBoxes border

This sample shows how to create a simply Report Database

Management.

This sample shows how to build a windows aplications.

How to use folders and manipulate them at run-time!

include "FiveWin.ch"

New cGetDir() function demo

Generic Index builder. A much better sample at IDE.prg

Testing Clipper InKey()

Testing a Object Inspector

FiveWin installation program ver 1.0

A 'virtual' Keyboard sample

Generating mailing labels - using FiveWin Report Preview

FiveWin labels!!! done with FiveWin !!!

Standard Windows ListBoxes with Bitmaps drawing

A nice Odometer developed by a FiveWin user

Drawing lines and some management colors

Learning to multiply numbers... For my son Lolo

A superb contribution by Jim Gale

FiveWin long filenames management. See also LongNam2.prg

Purpose: MDI child memo edit example

Checks the Clipper memory values from inside FiveWin

FiveWin MsgDate() function sample

FiveWin ODBC RDD early test

MSGDATE.PRG

MSSQL.PRG

MYVBX.PRG

NESTED.PRG

NEWHELP.PRG.

O2.PRG

OBJINSP.PRG

ODBC0.PRG

ODBC1.PRG

ODO.PRG

OWNERDRA.PRG

PEEKPOKE.PRG

PHONE.PRG

PP.PRG

PRG2EHT.PRG

PROFTP20.PRG

PROXHTTP.PRG

PROXIN.PRG

PROXNEWS.PRG

PROXOUT.PRG

PROXRA.PRG

RATEST.PRG

RC2PRG.PRG

RCIMPORT.PRG

RCLICK.PRG

RDD.PRG

RESMENU.PRG

SCANNED.PRG

SETALIAS.PRG

SM_BAR.PRG

SOCKCLI.PRG

SOCKSERV.PRG

TEST32.PRG

TESTADD.PRG

TESTALIG.PRG

ESTARGS.PRG

TESTARR1.PRG

TESTARR2.PRG

TESTARR3.PRG

TESTARR4.PRG

TESTARR5.PRG

TESTARR6.PRG

TESTATT.PRG

TESTAX.PRG

TESTBAR.PRG

TESTBAR2.PRG

TESTBAR3.PRG

TESTBARR.PRG

TESTBLOC.PRG

TESTBMP.PRG

TESTBMP1.PRG

TESTBMP2.PRG

TESTBMPD.PRG

TESTBORL.PRG

TESTBRAR.PRG

TESTBRU1.PRG

TESTBRUS.PRG

TESTBRW2.PRG

TESTBTN.PRG

TESTBTNB.PRG

FiveWin MsgDate() function sample

FiveWin ODBC RDD early test

Generating a VBX control at runtime contained at a DialogBox

Issuing multiple nested DialogBoxes

Sample showing how to work with new help techniques from FiveWin.

Very nice visual counter developed by a FiveWin user

FiveWin Object Inspector

FiveWin ODBC Tutorial 1

FiveWin ODBC capabilities

A nice Odometer developed by a FiveWin user

Testing 'ownerdraw' ListBoxes and ComboBoxes

Testing new FiveWin Peek and Poke functions...

FiveWin Phone - (c) FiveTech 1993-5

Some 3D graphics sample

Automatic documentation for a Class source code using a TLex

object

FiveWin Class TProxy demo

FiveWin Class TProxy demo

FiveWin Class TProxy demo

FiveWin Class TProxy demo

FiveWin Class TProxy demo

FiveWin Class TProxy demo

test de acceso al ras...

Windows RC to PRG file conversor utility - Developed by our

friend Oliver

FiveWin utility to import RCs and to generate source code

Sample showing how to control right click events

FiveWin Virtual RDD demo

Using PullDown Menus from resources

Mixing scanned images with data

FiveWin SetAlias() function demo

Description: Shows simple Toolbar mimicing MS-Office toolbar

Socket server connection sample

Socket server connection sample

Testing FiveWin 32 bits API new capabilities

Control Enable, Disable, Show and Hide features sample

New FiveWin powerfull automatic alignment techniques

Testing command line parameters

Reviewing arrays - using FiveWin TWBrowse

Reviewing two dimension arrays - using FiveWin TWBrowse

Managing arrays with no elements

A sample showing how to create controls inside a loop

Browse a multi-dimension array Created by Directory()

managing arrays with TcBrowse

FiveWin FAttrib() function demo

Our first Window in Windows !!!

This sample shows how to create a Management Menu whit

ButtonBar and Menu.

Advanced ButtonBar features demo

This sample shows how to create a test Bar with a Valid Get.

Advanced ButtonBar features demo

Disk-Storable CodeBlocks Objects

Images DataBase sample in FiveWin from resources

Sample managing bitmaps with adjust, scroll and new zoom effects!

This sample shows how to display fancy floating bitmaps. Very nice!

This sample shows how to create a simply Dynamic Bitmaps

Management.

Testing Loading and UnLoading Borland's BWCC.dll

Browsing a two dimensions array with FiveWin powerfull TWBrowse

Testing some nice brushes

Testing Brushes

FiveWin Quick browses feature sample

Defining ButtonBar buttons which uses Bitmaps files from disk

Testing the FiveWin Class TBtnBmp at a DialogBox from resources


FiveWin samples guide 2

We do recommend learning FiveWin through samples. Try them, modify them, feel free to use any part of them you may need.

TESTFFAM.PRG

TESTFILE.PRG

TESTFLAG.PRG

TESTFLD2.PRG

TESTFLD3.PRG

TESTFNT2.PRG

TESTFOC2.PRG

TESTFOCU.PRG

TESTFOLD.PRG

TESTFON2.PRG

TESTFONT.PRG

TESTFORM.PRG

TESTGET.PRG

TESTGETN.PRG

TESTGETR.PRG

TESTGFIL.PRG

TESTGRAF.PRG

TESTHARD.PRG

TESTHASH.PRG

TESTHD.PRG

ESTHELP.PRG.

TESTHEX.PRG

TESTHTM.PRG

TESTICO.PRG

TESTICON.PRG

TESTIDLE.PRG

TESTIERR.PRG

TESTIMG.PRG

TESTINI.PRG

TESTINI2.PRG

TESTJOY.PRG

TESTKEY.PRG

TESTKEY2.PRG

TESTKEYS.PRG

TESTLBX.PRG

TESTLBX2.PRG

TESTLBX3.PRG

TESTLBX4.PRG

TESTLFN.PRG

TESTLFN2.PRG

TESTLIB.PRG

TESTLIB2.PRG

TESTLOOP.PRG

TESTMAIL.PRG

TESTMBAR.PRG

TESTMBRS.PRG

TESTMDI.PRG

TESTMDI2.PRG

TESTMDI3.PRG

TESTMDI4.PRG

TESTMDI5.PRG

TESTMDI6.PRG

TESTMDI7.PRG

TESTMDI8.PRG

TESTMDI9.PRG

TESTMDIX.PRG

TESTMDIY.PRG

TESTMEM2.PRG

TESTMEMO.PRG

TESTMENU.PRG

TESTMETR.PRG

TESTMGET.PRG

TESTMMD.PRG

TESTMMT.PRG

TESTMNU.PRG

TESTMNU2.PRG

TESTMNU3.PRG

TESTMNU4.PRG

TESTMNU5.PRG

TESTMOUS.PRG

TESTMRU.PRG

TESTMSG.PRG

TESTMSG2.PRG

TESTMSG3.PRG

TESTNET.PRG

TESTNEWS.PRG

TESTNOM.PRG

TESTNOMO.PRG

TESTNTX.PRG

TESTOBJ.PRG

TESTOERR.PRG

TESTOLE.PRG

TESTOP.PRG

TESTOUT.PRG

TESTPAGE.PRG

TESTPARA.PRG

TESTPARS.PRG

TESTPASS.PRG

TESTPIE.PRG

TESTPLAY.PRG

TESTPOLY.PRG

TESTPOP.PRG

TESTPOP2.PRG

TESTPORT.PRG

TESTPRN.PRG

TESTPRN1.PRG

TESTPRN2.PRG

TESTPRN4.PRG

TESTPROF.PRG

TESTPROX.PRG

TESTRAD.PRG

TESTRAD2.PRG

TESTRAD3.PRG

TESTRAD4.PRG

TESTRAD5.PRG

TESTRAND.PRG

TESTRAS.PRG

TESTREAD.PRG

TESTREG.PRG

TESTREP1.PRG

TESTRES.PRG

TESTRES2.PRG

TESTRL.PRG

TESTRPT2.PRG

TESTRPT3.PRG

TESTRPT4.PRG

TESTRPT5.PRG

TESTRUN.PRG

TESTSAY.PRG

TESTSCRL.PRG

TESTSERV.PRG

TESTSIZE.PRG

TESTSMTP.PRG

TESTSPL1.PRGs

TESTSPL2.PRG

TESTSPL3.PRG

TESTSPL4.PRG

TESTSPL5.PRG

TESTSPL6.PRG

TESTSTR.PRG

TESTSTR2.PRG

TESTSTY2.PRG

TESTSTYL.PRG

TESTSYSM.PRG

TESTTABS.PRG

TESTTCB2.PRG

TESTTCB3.PRG

TESTTCBR.PRG

TESTTFN.PRG

TESTTIM2.PRG

TESTTIM3.PRG

TESTTIME.PRG

TESTTOK.PRG

TESTTOOL.PRG

TESTTOP.PRG

TESTTXED.PRG

TESTUZIP.PRG

TESTVBX1.PRG

TESTVBX2.PRG

TESTVBX3.PRG

TESTVBX4.PRG

TESTVBX5.PRG

TESTVBX6.PRG

TESTVERS.PRG

TESTVID.PRG

TESTWAIT.PRG

TESTWHEN.PRG

TESTWRIT.PRG

TESTWSTY.PRG

TESTYACC.PRG

TESTZIP.PRG

THREADS.PRG

TOOLTIP.PRG

TOPAPP.PRG

TSTBTNBM.PRG

TUTOR01.PRG

TUTOR02.PRG

TUTOR03.PRG

TUTOR04.PRG

TUTOR05.PRG

TUTOR06.PRG

TUTOR07.PRG

TUTOR08.PRG

TWOCLASS.PRG

USERID.PRG

VBXCLASS.PRG

VIEWICO.PRG

WEBCLIEN.PRG

WEBSERV.PRG

WIN95.PRG

WIN95_2.PRG

WINEXEC.PRG

WININSPE.PRG

EnumFontFamilies() sample

FiveWin Object Oriented ascii files management demo 1

Testing Windows different system info flags

Two folders at a time! Wow!

Dinamically building a folder ontop of a Dinamic DialogBox

clude "FiveWin.ch"

Sample showing how to detect Dialog focused control

Controlling focus from one window to another

Testing FiveWin own folders controls support

Some tests with fonts capabilities

Examples of using different Font on the Window

Testing the new FiveWin 2.0 Class TForm

Testing a GET

Testing a GET editing a number

Testing a GET with right justification

Testing the new 4th parameter of cGetFile() function

Some bussiness graphics using FiveWin

Returns the serial number of the harddisk !!!

Testing the new FiveWin nStrHash() function

FiveWin new nSerialHD() number to check the HardDisk

serial number

This sample shows how to use a system windows help.

Testing the FiveWin Integer to Hexadecimal conversion function

ction Main()

Animations using Icons and Timers

Playing with icons...

FiveWin - Idle intervals management control –

Background processing!

SetIEMsg() sets the default Clipper internal error message

clude "FiveWin.ch"

Sample showing how to use INI files with FiveWin

Using Windows .INI files FOR configuration inFormationê

JoyStick Interface functions for FiveWin.

Testing Keyboard management

clude "FiveWin.ch"

SET KEY management in FiveWin

ListBox use sample

Placing bitmaps at standard ListBoxes in FiveWin

Using ListBoxes to perform simple selections

Using ListBoxes with Multiple-Selection

Testing Windows 95 long filenames FiveWin support functions

Many thanks to Jim Gale for his superb feed-back

FiveWin - LIB files management functions !!!

Testing the new FiveWin TLibFile Class

Sample showing how to create controls inside loops...

FiveWin - Windows MAPI (mail services) support demonstration

Testing different fonts in the MsgBar

Managing multiple ButtonBars sample

Working with MDI enviroments

Starting learning MDI enviroments

Starting learning MDI enviroments

This is an example of how to place controls inside a MDIChild

Using MDIChilds with user defined styles

Controlling MDI menus - Dynamically changing MDIChild

windows menus

How to place a Bitmap logo onto a MDI environment!

Placing a Browse inside a MdiChild window !

Testing the PullDown menu predefined built options

This is an example of how to place controls inside a MDIChild

Using MDIChildren with user defined styles ä

Some customers tests

This sample shows how to manage a Memo editing

A sample for use a simply menu...

Testing FiveWin own meter controls

Some testing on INI files, Dialogs and printing

Testing the mouse in a MDI environment

FiveWin MsgMeter() function working sample

Storing a PullDown menu into a DBF

Testing PullDown Menus

PullDown Menu sample

Some PullDown menu samples

This sample shows how to perform a MenuItem action,

Testing the Mouse events

FiveWin new MRU technology ! Really cool !!!

Testing Message standard Dialog Boxes

New Msg... functions feature which automatically

converts value to strings

The new FiveWin messageBars !!!

Using Windows some NetWork DialogBoxes services

FiveWin Class TNewsServer demo

Some NonModal DialogBox testing

Testing Non-Modal DialogBoxes

Testing the FiveWin cNtxKey() function to extract a NTX key

from a file

FiveWin - OBJ files manipulation sample

Testing the new FiveWin OBJECTS engine: User Defined

error handler!

OLE2 support from FiveWin !!!

Testing the new FiveWin OBJECTS 4.0 engine operators-

overloading feature!

clude "Fivewin.ch"

Testing the new FiveWin TPages Class

Testing Clipper GetEnv() function from Windows

Testing FiveWin parser machine

Small sample showing how to request a password previous

to main window

Testing Pie function and Pie parameters usage

Testing FiveWin input Recording and Playback features

Drawing Polygons using Windows API

Testing Popup Menus in FiveWin

Testing a Popup Menu from resources

Testing new FiveWin hardware ports manipulation functions

Printing a whole window sample

This sample shows how to select from code the orientation

of the printer

Sample showing how to manage the printer object

clude "FiveWin.ch"

FiveWin Profiling techniques

FiveWin Class TProxy demo

Radio Buttons management sample

Testting some radio buttons

More samples with RadioButtons

More samples with RadioButtons

Radios and WHEN on a GET

Controlling MDI menus - Dynamic MDIChild windows menus

clude 'Fivewin.ch'

Testing FRead() function under Windows

Managing Register services from FiveWin

This is a demo of the FiveWin report Engine

Sample showing how to use dialogs stored inside a DLL

Testing FiveWin HasResources( <cExeName> ) function

FiveWin ClipMore equivalent functions test

FiveWin own report engine sample

Some more reports

More reports...

More reports...

This sample shows how to use new FiveWin Run()

function which executes

A small sample showing how to use :Say() with fonts

Sample how to use ScrollBars

FiveWin WebServer sample

How to control authorized position, size and tracking dimensions

Testing FiveWin new Internet Outgoing mail (SMTP protocol) Class

Testing FiveWin splitter controls

Testing FiveWin splitter controls

Testing FiveWin splitter controls

Testing FiveWin splitter controls

Testing FiveWin splitter controls

Testing FiveWin splitter controls

We are loading strings from a RC = TestStr.rc

Testing FiveWin Class TString (strings larger than 64 Ks !!!)

A Dialog Box with no border and caption

Using alternatives window styles sample

Redefining the system menu of a window

Testing new FiveWin Tabs !!!

FiveWin column based browse sample

Reviewing arrays - using FiveWin TCBrowse

FiveWin column based browse sample

Testing the new function cTempFile which returns a

temporary filename

Using Time-Class Objects

This sample shows how to call a function in an interval time.

Using Timers. Timers are also Objects!

Testing the FiveWin function StrToken()

Testing Windows ToolHelp.dll

Testing how to keep an application at top

Testing Class TTxtEdit

FiveWin ZIP files unzip management !!!

FiveWin - VBX Visual Basic controls management tutorial

FiveWin - VBX Visual Basic controls management tutorial

FiveWin - VBX Visual Basic controls management tutorial

FiveWin: Using Tabs VBXs samples

FiveWin - VBX Visual Basic controls management tutorial

FiveWin - VBX Visual Basic controls management tutorial

Do you want to see the Windows & Dos Version

A sample showing Multimedia VIDEO extensions capabilities

Testing the FiveWin MsgWait() function

Testing the WHEN clause in controls

Sample showing how to manipulate external apps from FiveWin

Testing Windows Styles!

Testing FiveWin YACC Machine !!!

Fivewin Zip Files management !!!

Threads support. Just for FiveWin++

This sample shows how to easily implement 'tool-tips' in FiveWin!

Sample showing how to put on top any other application

A nice text + BitmapedButtons MultiMedia sample!

Typical Welcome message, from Windows!

Our first Window in Windows !!!

Our first Window, now with Control events examples and with a

message bar

We are going to build a PullDown menu and we are going to

assign it

This is the same exercise we have done at Tutor04, but now

In this exercise we are going to build Dialog Boxes directly from

More work on previuos Tutor06

First works with browses

How to declare two Classes in just one PRG file

Use this function to Register your EXEs before distributing them

VBX internal inspector

An easy sample showing how to develop an Icons viewer

FiveWin Class TWebClient demo

FiveWin powerfull WebServer sample

FiveWin Windows 95 new controls implementation

Managing Windows 95 Trees !!!

Generic winexec tester. It will display any app WinExec return code

Inspecting the Windows API msgs. Just for advanced users!


xBase Commands

More:


Introduction

One of the great advantages of xBase is its syntax. Wayne Rattlif really did an excellent work designing a syntax with 'human language' for dBase. xBase commands are the highest level of abstraction on a OOPS architecture.

xBase commands let us think only in functionality. When you need to quickly develop an application you should use xBase commands. You will only have to worry about the PS layer under the xBase commands when you plan to expand FiveWin.

Clipper 5's extraordinary preprocessor lets us apply a really easy Windows programming system based on xBase commands. Under this layer there exist Objects, functions, data and Windows API calls.

Most xBase commands are built on Objects. When we write:

DEFINE WINDOW oWnd FROM 1, 1 TO 20, 50

What we are doing is using Objects, however we don't have to worry about them. There is no need to. xBase commands let us focus on what we want to happen and not about how things get done.


XBase common elements

We have paid particular attention into the syntax of FiveWin such as using the same clause to do the same thing in similar circumstances. This means that as soon as you learn these few rules, you may control a lot of different FiveWin features.

We will keep extending this basic concept to manage all the different parts of the Windows API. Having just a unique xBase interface to manage the Windows API will let you concentrate in the goal of your application and not in the details.

More:


xBase clauses

Ddescription

DEFINE

ACTIVATE

:End()

OF

RESOURCE

NAME

DISK, FILENAME, FILE

SIZE

All the objects in FiveWin get created using the key word

DEFINE:DEFINE <Class> <Object> [<more clauses>]

As example, to create a window we do:

DEFINE WINDOW oWnd ...

To create a Dialog Box: DEFINE DIALOG oDlg ...

To create an icon: DEFINE ICON oIco ...

To create a report: DEFINE REPORT oRpt ...

Remember to use DEFINE to create anything!

Everything in FiveWin start working using the key ACTIVATE

ACTIVATE <Class> <Object> [<more clauses>]

As example, to activate a window we do:

ACTIVATE WINDOW oWnd ...

To activate a report: ACTIVATE REPORT oRpt ... To

activate a Dialog Box: ACTIVATE DIALOG oDlg ...

To activate a timer: ACTIVATE TIMER oTmr ...

Remember to use ACTIVATE to make things work!

though this is an OOPS message, we use it extensively in

FiveWin to end the execution of something:

<Object>:End()

As example, to end the execution of a window we use:

oWnd:End()

To end a Dialog Box: oDlg:End()

To end a timer: oTmr:End()

To end a report: oRpt:End()

We use the OOPS message instead of a xBase command, because

we may issue it from many different

places, where is not possible to use an xBase command:

REDEFINE BUTTON ID ID_END OF oDlg ;

ACTION oDlg:End()

Every time we need to specify the owner or container of an Object,

we use OF:

REDEFINE BUTTON ID ID_OK OF oDlg

The clause OF means: "belongs to", "it is contained in", "its owner is".

For example, to specify the owner of a DialogBox:

DEFINE DIALOG oDlg RESOURCE "Test" OF oWnd

For a child window: DEFINE WINDOW oWnd2 TITLE "Test" ; OF oWnd1

For a control: REDEFINE GET cName ID ID_NAME OF oDlg

For a font: DEFINE FONT oFont NAME "Arial" ;

SIZE 0, -20 OF oPrn

You may use any of these clauses to specify that an Object RESNAME

has to be built from resources

DEFINE ... RESOURCE <cResourceName>

For example, to create an icon from resources, we do:

DEFINE ICON oIco RESOURCE "MyIcon"

To create a Dialog Box:

DEFINE DIALOG oDlg RESOURCE "Clients"

To create a cursor:

DEFINE CURSOR oCrs RESOURCE "Eye"

Remember: Always use RESOURCE clause to create

an Object from resources stored inside the

same EXE (rc resources) or stored inside a DLL.

You may use any of these clauses to specify than an Objec

t has to be loaded from a file in disk.

DEFINE ... FILENAME <cFileName>

For example to use a button bitmap which picture i

s inside a BMP file we do:

DEFINE BUTTON OF oBar FILENAME "Exit.bmp"

To create a bitmap control from disk we do:

REDEFINE BITMAP oBmp ID ID_PHOTO OF oDlg ;

FILENAME "Photo.bmp"

Remember: Always use FILENAME clause to use a file stored at disk.

<nWidth>, Every time we have to specify some

pixel dimensions we use <nHeight> the SIZE clause.

Remember: Always use SIZE to specify certain dimensions.


Windows Commands

Creating a new Window:

DEFINE WINDOW <oWnd> ;

[ FROM <nTop>, <nLeft> TO <nBottom>, <nRight> ] ;

[ TITLE <cTitle> ] ;

[ <color: COLOR, COLORS> <nClrFore> [,<nClrBack>] ];

[ OF <oParent> ] ;

[ BRUSH <oBrush> ] ;

[ CURSOR <oCursor> ] ;

[ ICON <oIcon> ] ;

[ MENU <oMenu> ] ;

[ STYLE <nStyle> ] ;

[ BORDER [ NONE | SINGLE ] ] ;

[ NOSYSMENU | NO SYSMENU ] ;

[ NOCAPTION | NO CAPTION | NO TITLE ] ;

[ NOICONIZE | NOMINIMIZE ] ;

[ NOZOOM | NO ZOOM | NOMAXIMIZE | NO MAXIMIZE ] ;

[ VSCROLL | VERTICAL SCROLL ] ;

[ HSCROLL | HORIZONTAL SCROLL ]

oWnd>

<nTop>

<nLeft>

<nBottom>

<nRight>

<cTitle>

<oParent>

<oBrush>

<oCursor>

<oIcon>

<oMenu>

<nStyle>

<nClrFore>

<nClrBack>

A reference to the Window Object.

Window coordinates on screen. We simulate text coordinates.

The title of the Window.

A reference to the Parent Window.

Already created Brush Object to be used as background of

the Window. Use DEFINE BRUSH ... to create it. This parameter is

optional.

A reference to the Cursor Object to display over this control

.A reference to an Icon Object to be used by the Window. Use

DEFINE ICON ... to create it. This parameter is optional.

An already created Menu Object. Use MENU ... ENDMENU inside

a function as in examples. This parameter is optional.

A numeric value which indicates a special API style. [ Just

for advanced FiveWin users.]

The colors to use for the windows. They may be numeric RGB colors

or xBase string colors.

ACTIVATE WINDOW <oWnd> ;

[ ICONIZED | NORMAL | MAXIMIZED ] ;

[ ON LEFT CLICK <uLClick> ] ;

[ ON LBUTTONUP <uLButtonUp> ];

[ ON RIGHT CLICK <uRClick> ] ;

[ ON MOVE <uMove> ] ;

[ ON RESIZE <uResize> ] ;

[ ON PAINT <uPaint> ] ;

[ ON KEYDOWN <uKeyDown> ] ;

[ ON INIT <uInit> ]

[ ON UP <uUp> ];

[ ON DOWN <uDown> ];

[ ON PAGEUP <uPgUp> ];

[ ON PAGEDOWN <uPgDn> ];

[ ON LEFT <uLeft> ];

[ ON RIGHT <uRight> ];

[ ON PAGELEFT <uPgLeft> ];

[ ON PAGERIGHT <uPgRight> ];

[ ON DROPFILES <uDropFiles> ];

[ VALID <uValid> ];

<oWnd>

<uLClick>

<uRClick>

<uMove>

<uResize>

<uPaint>

<uKeyDown>

<uInit>

A reference to the Window Object.

An action to be performed when the left button of the mouse is

clicked over the Window.

An action to be performed when the right button of the mouse

is clicked over the Window.

An action to be performed every time the Window is moved.

An action to be performed every the Window is resized.

An action, generally drawing action, to be performed every

the Window is painted.

An action to be performed every a key is pressed being the

Window focused.

An action to be performed, generally some initialization,

when the Window is being initialized.


Bar

Reating a Button Bar from source code

DEFINE BUTTONBAR [ <oBar> ] ;

[ SIZE | BUTTONSIZE | SIZEBUTTON <nWidth>,;<nHeight> ] ;

[ 3D | 3DLOOK | _3D | _3DLOOK ] ;

[ TOP | LEFT | RIGHT | DOWN | FLOAT ] ;

[ OF | WINDOW | DIALOG <oWnd> ] ;

[ CURSOR <oCursor> ]

Creating a ButtonBar from source code and placing it at a specific location

@ <nRow>, <nCol> BUTTONBAR [ <oBar> ] ;

[ SIZE <nWidth>, <nHeight> ] ;

[ BUTTONSIZE <nBtnWidth>, <nBtnHeight> ] ;

[ 3D | 3DLOOK | _3D | _3DLOOK ] ;

[ TOP | LEFT | RIGHT | BOTTOM | FLOAT ] ;

[ OF | WINDOW | DIALOG <oWnd> ] ;

[ CURSOR <oCursor> ] ;

Defining a button of the buttonbar

DEFINE BUTTON [<oBtn>] ;

[ OF | BUTTONBAR <oBar> ] ;

[ NAME | RESNAME | RESOURCE <cResName1>;

[,<cResName2>, <cResname3>] ] ;

[ FILE | FILENAME | DISK <cBmpFile1>;

[,<cBmpFile2> <cBmpFile3>] ] ;

[ ACTION | EXEC <uAction> ] ;

[ GROUP ] ;

[ MESSAGE <cMsg> ] ;

[ ADJUST ] ; * Obsolete

[ WHEN <uWhen> ] ;

[ TOOLTIP <cToolTip> ]

[ PRESSED <lPressed> ]

[ ON DROP <bDrop>]

[ AT <nPos> ];

[ PROPMT < cPrompt> ];

[ FONT <oFont> ];

[ NO BORDER <lNoBorder> ];

[ MENU <oPopup> ]

To redefine a button placed on a dialogbox in a resource. (just a button, not a buttonbar). This lets you have buttons with bitmaps inside DialogBoxes without having to use Borland's BWCC.DLL

REDEFINE BTNBMP [<oBtn>] ;

[ ID <nId> ] ;

[ OF | BUTTONBAR <oBar> ] ;

[ NAME | RESNAME | RESOURCE <cResName1> [,<cResName2>,cResname3>] ] ;

[ FILE | FILENAME | DISK <cBmpFile1> [,<cBmpFile2>, <cBmpFile3>]]

[ ACTION | EXEC | ON CLICK <uAction> ] ;

[ MESSAGE <cMsg> ] ;

[ ADJUST ] ; * Obsolete

[ WHEN <uWhen> ] ;

[ UPDATE <lUpdate> ] ;

[ TOOLTIP <cToolTip> ] ;

[ PROPMT < cPrompt> ];

[ FONT <oFont> ];

[ NO BORDER <lNoBorder> ]

To create a bitmap button from source code, and place it at any container window

@ <nRow>, <nCol> BTNBMP [<oBtn>] ;

[ NAME | RESNAME | RESOURCE <cResName1> [,<cResName2>, <cResName3>] ] ;

[ FILE | FILENAME | DISK <cBmpFile1> [,<cBmpFile2>, <cBmpFile3>] ]

[ SIZE <nWidth>, <nHeight> ] ;

[ ACTION <uAction> ] ;

[ OF | WINDOW | DIALOG <oWnd> ] ;

[ MESSAGE <cMsg> ] ;

[ WHEN <uWhen> ] ;

[ ADJUST ] ; * Obsolete

[ UPDATE ] ;

PROPMT < cPrompt> ];

[ FONT <oFont> ];

[ NO BORDER <lNoBorder> ]

Note: The clause ADJUST is not supported because now the bitmaps background color is automatically adjusted to his window or control conteiner. The pixel 0,0 (Left-Top) indicates the mask color to use for the adjustment. It is important that the color in that pixel is not used on any other part of the bitmap except where the mask should be applied. This kind of color adjustment is not possible with bitmap streching

You may also place a buttonbar on a DialogBox. To do it, just create the buttonbar from the ON INIT clause when activating the DialogBox.

At the ON INIT clause, a DialogBox behaves like a standard window.

<oBar> A reference to the Bar Object.

<nWidth> <nHeight> The width and height of the buttons of the bar. By default is 28x28 pixels

<oWnd> A reference to the container Window of the bar.

<oCursor> A reference to the mouse cursor object to use for the bar.

<oBtn> A reference to the BitmapButton Object.

<cBmpFile1> <cBmpFile2>

<cBmpFile3> The name of the Bitmap to display. Optionally you may specify

a second bitmap for animation. This is used for accessing

bitmaps stored on the hard disk (my.bmp)

<cResName1> <cResName2>

<cResName3> The resource name of the Bitmap to display.

Optionally you mayspecify a second bitmap for animation.This is used for accessing bitmaps stored in a Resource file (and .rc file or a .dll file)

<uAction> The action to be performed when clicking the Button.

<cMsg> The message to display on the message bar of the container Window of the Bar object which contains the BitmapButton.

<uWhen> An expression that indicates if the button of the buttonbar is enabled or not.

<nId> The identifier for the button placed at a DialogBox.

<cToolTip> The text to show on a associated floating tooltip.

<bDrop> The action to be performed when

<nPos> An optional left position coordinate.

<cPrompt> An optional prompt to display.

<oFont> An optional font to use for the prompt.

<lNoBorder> To show a flat style.

<bDrop> The action to perform when an object is droped over the button.

<lPressed> To show the button as pressed.

<oPopup> Object Menu Popup to show when the button is pressed

CLAUSES

3D 3DLOOK _3D _3DLOO To display the buttonbar with a gray 3D look.

TOP LEFT RIGHT DOWN clicking on the buttonbar also popups a menu to select dinamically

a new position.

FLOAT Places the buttonbar on a floating window.For the buttons on the buttonbar (BTNBMP)

ADJUST To automatically adjust the bitmap to the size of button.

GROUP Starts a new "group" of buttons in the ButtonBar.You may have as many groups as you need.

UPDATE For bitmap buttons placed on a DialogBox (without a buttonbar). The button will update its image automatically when doing a oDlg:Update().

Example: SAMPLES\TestBar.prg


Bitmaps

Creating a bitmap from source code

@ <nRow>, <nCol> BITMAP [ <oBmp> ] ;

[ NAME | RESNAME | RESOURCE <cResName> ] ;

[ FILE | FILENAME | DISK <cBmpFile> ] ;

[ NOBORDER | NO BORDER ] ;

[ SIZE <nWidth>, <nHeight> ] ;

[ OF | WINDOW | DIALOG <oWnd> ] ;

[ ON CLICK | ON LEFT CLICK <uLClick> ] ;

[ ON RIGHT CLICK <uRClick> ] ;

[ SCROLL ] ;

[ ADJUST ] ;

[ CURSOR <oCursor> ] ;

[ PIXEL ] ;

[ MESSAGE <cMsg> ] ;

[ UPDATE ] ;

[ WHEN <WhenFunc> ] ;

[ VALID <uValid> ] ;

[ DESIGN ]

Creating a bitmap from resources

DEFINE BITMAP [ <oBmp> ] ;

[ NAME | RESNAME | RESOURCE <cResName> ] ;

[ FILE | FILENAME | DISK <cBmpFile> ] ;

[ OF | WINDOW | DIALOG <oWnd> ]

REDEFINE BITMAP [ <oBmp> ] ;

[ ID <nId> ] ;

[ OF | WINDOW | DIALOG <oWnd> ] ;

[ NAME | RESNAME | RESOURCE <cResName> ] ;

[ FILE | FILENAME | DISK <cBmpFile> ] ;

[ ON ClICK | ON LEFT CLICK <uLClick> ] ;

[ ON RIGHT CLICK <uRClick> ] ;

[ SCROLL ] ;

[ ADJUST ] ;

[ CURSOR <oCursor> ] ;

[ MESSAGE <cMsg> ] ;

[ UPDATE ] ;

[ WHEN <WhenFunc> ] ;

[ VALID <uValid> ] ;

[ TRANSPAREN ]

<nRow>, <nCol> The coordinates on screen. We simulate Text coordinates.

<oBmp> A reference to the Bitmap Object.

<cResName> The name of the bitmap resource bitmap when loading a bitmap from a .RC, .RES or a .DLL file .

<cBmpFile> The name of the BMP file when loading a bitmap directly from a BMP file.

<nWidth> The desired width of the bitmap.

<nHeight> The desired height of the bitmap.

<oWnd> The container window of the Bitmap control.

<uLClick> The action(s) to be performed when left clicking over the Bitmap.

<uRClick> The action(s) to be performed when right clicking over the Bitmap

<oCursor> A reference to the Cursor Object to display over this control.

<cMsg> The associated message of this control.

<nId> The numeric resource identifier of the Control.

<WhenFunc> An expression indicating when this control will be active or not

<uValid> An expression to evaluate when this control looses its focus

CLAUSES

NO BORDER

NOBORDER It does not place a border around the control

UPDATE This control may be updated from TDialog:Update() METHOD

PIXEL To use pixel coordinates instead of Text coordinates

SCROLL Enable the use of scrollbars to scroll the bitmap into its visible area. This let the user review bitmaps larger than the control.

ADJUST Automatically adjusts the bitmap(s) to the size of the control.

TRANSPAREN The bitmap pixel located at 0, 0 is used as the color for a mask to turn its background transparent.

DESIGN Allows the user to move and resize with the mouse

See also: Timage


Browse

Defining a Browse Object from source code

@ <nRow>, <nCol> LISTBOX [ <oBrw> ] ;FIELDS <Flds,...> ;

[ ALIAS <cAlias>] ;

[ FIELDSIZES | SIZE | COLSIZES <aColSizes,...> ] ;

[ HEAD | HEADER | HEADERS | TITLE <aHeaders,...> ] ;

[ SIZE <nWidth>, <nHeigth> ] ;

[ SELECT <cField> FOR <uValue1> [ TO <uValue2>] ] ;

[ ON CHANGE <uChange> ] ;

[ ON RIGHT CLICK <uRClick> ] ;

[ ON [LEFT] CLICK <uLClick> ] ;

[ ON [LEFT] DBLCLICK <uDblClick> ] ;

[ FONT <oFont>] ;

[ CURSOR <oCursor>] ;

[ COLOR | COLORS <nClrFore> [,<nClrBack>] ] ;

[ MESSAGE <cMsg>] ;

[ UPDATE ] ;

[ PIXEL ] ;

[ WHEN <uWhen> ] ;

[ DESIGN ] ;

[ VALID <ValidFunc> ] ;

[ ACTION <uAction,...> ] ;

[ OF | DIALOG <oDlg> ]

Redefining a Browse from resources

REDEFINE LISTBOX [ <oBrw> ] ;FIELDS [ <cFields,...>] ;

[ ALIAS <cAlias> ] ;

[ ID <nId> ] ;

[ FIELDSIZES | SIZES | COLSIZES <aColSizes,...> ] ;

[ HEAD | HEADER | HEADERS| TITLE <aHeaders,...> ] ;

[ SELECT <cField> FOR <uValue1> [ TO <uValue2> ] ] ;

[ ON CHANGE <uChange> ] ;

[ ON RIGHT CLICK <uRClick> ] ;

[ ON [LEFT] CLICK <uLClick> ] ;

[ ON [LEFT] DBLCLICK <uDblClick> ] ;

[ FONT <oFont> ] ;

[ CURSOR <oCursor> ] ;

[ COLOR | COLORS <nClrFore> [,<nClrBack>] ] ;

[ MESSAGE <cMsg> ] ;

[ UPDATE ] ;

[ WHEN <uWhen> ] ;

[ VALID <ValidFunc> ] ;

[ ACTION <uAction,...> ] ;

[ OF | DIALOG <oDlg> ]

<oBrw> A reference to the TWBrowse Object.

<nRow> <nCol> Position on container window. We simulate text coordinates.

<Flds...> A list of text expressions to display as columns. If an expression is of numeric type, TWbrowse will manage it as the handle of a bitmap to be displayed.

<aColSizes> A list of sizes for each column in pixels.

<aHeaders> A list of text expressions for headers.

<nId> Is the numeric identifier of the TWBrowse control.

<nWidth> <nHeigth> The desired size of the TWbrowse control in pixels.

<uChange> An action to be performed when selecting a new row.

<uRClick> An action to be performed when right clicking

<uLClick> An action to be performed when left clicking

<uLDblClick> An action to be performed when Double Left clicking

<oFont> A reference to the Font Object to be used with the LISTBOX.

<ValidFunc> An expression or function to be validated when the ListBox loses its focus.

<nClrFore> Foreground color as a RGB number, or as a xBase string

<nClrBack> Background color as a RGB number

<uAction,...> A list of actions to be executed when a certain column header is clicked with the mouse.

<cField> Must be the Field key of the current INDEX !!!

<oDlg> The object that contain the TWbrowse control.

CLAUSES

DESIGN Allows the user to move and resize with the mouse

PIXEL To use pixel coordinates instead of Text coordinates

See also: TcBrowse


Brushes

Defining a Brush from source code

DEFINE BRUSH <oBrush> ;

[ STYLE <cStyle> ] ;

[ COLOR <nRGBColor> ] ;

[ FILE | FILENAME | DISK <cBmpFile> ];

[ RESOURCE | NAME | RESNAME <cBmpRes> ]

RELEASE BRUSH <oBrush>

Assigning a Brush to an Window

SET BRUSH ;

[ OF <oWnd> ] ;

[ TO <oBrush> ]

<oBrush> A reference to the Brush Object.

<cStyle> One of the styles listed below.

<nRGBColor> A color in RGB format. Use nRGB() function.

<cBmpFile> The name of a BMP file to use to build the Brush.

<cBmpRes> The name of a BMP in the resource.

<oWnd> A reference to the owner Window (Container) of the Brush.

DIFFERENT STYLES:

New styles: BORLAND, TILED, BRICKS

Standard styles: DIAGONAL, HORIZONTAL, VERTICAL, FDIAGONAL, BDIAGONAL, CROSS, DIAGCROSS


BtnBmp

Bitmapped buttons.

These buttons are also explained on the command Bar, but you also can place them anywhere not only on the tool bar.

Creating a bitmap button from source code:

@ <nRow>, <nCol> BTNBMP [<oBtn>] ;

[ NAME | RESNAME | RESOURCE <cResName1> [,<cResName2>, cResName3>] ] ;

[ FILE | FILENAME | DISK <cBmpFile1> [,<cBmpFile2>, <cBmpFile3>]];

[ SIZE <nWidth>, <nHeight> ] ;

[ ACTION <uAction> ] ;

[ OF | WINDOW | DIALOG <oWnd> ] ;

[ MESSAGE <cMsg> ] ;

[ WHEN <uWhen> ] ;

[ ADJUST ] ;* Obsolete

[ UPDATE ] ;

[ PROPMT < cPrompt> ];

[ FONT <oFont> ];

[ NO BORDER <lNoBorder> ]

Creating a bitmap button from resources:

REDEFINE BTNBMP [<oBtn>] ;

[ NAME | RESNAME | RESOURCE <cResName1> [,<cResName2>,cResname3>] ] ;

[ FILE | FILENAME | DISK <cBmpFile1> [,<cBmpFile2>, cBmpFile3>]];

[ ACTION | EXEC | ON CLICK <uAction> ] ;

[ ID <nId> ] ;

[ OF <oWnd> ] ;

[ MESSAGE <cMsg> ] ;

[ ADJUST ] ; * Obsolete

[ WHEN <uWhen> ] ;

[ UPDATE <lUpdate> ] ;

[ TOOLTIP <cToolTip> ] ;

[ PROMPT < cPrompt> ];

[ FONT <oFont> ];

[ NO BORDER <lNoBorder> ]

<oBtn> A reference to the Button Object

<nRow> <nCol> The coordinates on screen. We simulate Text coordinates

<cResName1> <cResName2>

<cResName3> The resource name of the Bitmap to display. Optionally you mayspecify a second bitmap for animation.This is used for accessing bitmaps stored in a Resource file (and .rc file or a .dll file)

<cBmpFile1> <cBmpFile2>

<cBmpFile3> The name of the Bitmap to display. Optionally you may specify a second bitmap for animation. This is used for accessing bitmaps stored on the hard disk (my.bmp)

<nWidth> <nHeight> The width and height of the buttons of the bar

<oWnd> A reference to the container Window.

<uAction> The action to be performed when clicking the Button.

<cMsg> The message to display on the message bar of the container Window of the Bar object which contains the BitmapButton.

<uWhen> An expression that indicates if the button of the buttonbar is enabled or not.

<nId> The identifier for the button placed at a DialogBox.

<cToolTip> The text to show on a associated floating tooltip.

<nPos> An optional left position coordinate.

<cPrompt> An optional prompt to display.

<oFont> An optional font to use for the prompt.

<lNoBorder> To show a flat style.

CLAUSES

ADJUST * Obsolete To automatically adjust the bitmap to the size of button. This clause is obsolete and is not supported any more

UPDATE For bitmap buttons placed on a DialogBox (without a buttonbar). The button will update its image automatically when doing a oDlg:Update().

Note: The clause ADJUST is not supported because now the bitmaps background color is automatically adjusted to his window or control conteiner. The pixel 0,0 (Left-Top) indicates the mask color to use for the adjustment. It is important that the color in that pixel is not used on any other part of the bitmap except where the mask should be applied. This kind of color adjustment is not possible with bitmap streching

See also: Buttons


Buttons

Creating Buttons from source code

@ <nRow>, <nCol> BUTTON [ <oBtn> ][ PROMPT <cCaption> ] ;

[ SIZE <nWidth>, <nHeight> ] ;

[ ACTION <uAction> ] ;

[ OF | WINDOW | DIALOG <oWnd> ] ;

[ MESSAGE <cMsg> ] ;

[ WHEN <WhenFunc> ] ;

[ DEFAULT ] ;

[ HELP | HELPID | HELP ID <nHelpId> ] ;

[ FONT <oFont> ] ;

[ PIXEL ] ;

[ DESIGN ] ;

[ UPDATE ] ;

[ VALID <uValid> ] ;

[ CANCEL ]

Using Buttons from resources

REDEFINE BUTTON [<oBtn>] ;

[ ID <nId> ] ;[ OF | WINDOW | DIALOG <oDlg> ] ;

[ ACTION <uAction> ] ;

[ HELP | HELPID | HELP ID <nHelpId> ] ;

[ MESSAGE <cMsg> ];

[ UPDATE ];

[ WHEN <WhenFunc> ] ;

[ VALID <uValid> ];

[ PROMPT <cCaption> ] ;

[ CANCEL ]

<nRow>, <nCol> The coordinates of the Button. They mimic text mode coordinates.

<oBtn> A reference to the Button Object.

<cCaption> The label of the Button.

<nHelpId> The help topic identifier of the Button.

<oWnd> The container window of the Button.

<uAction> The action to be performed when the Button is pressed.

<oFont> A reference to the Font Object to use with the Button.

<nWidth> <nHeigth> The dimensions of the Button.

<cMsg> The associated message of this control

<WhenFunc> It is an expression to evaluate indicating if the control is or not enable.

<nId> The numeric resource identifier of the Control.

<uValid> An expression to validate when the control is going to lose the focus.

CLAUSES

DEFAULT For default PushButtons: Automatically executes when the user press Enter, even from other controls.

Use this clause only when building the Button from source code. When using resources, this clause must be specifies from the resource editor.

DESIGN Allows the user to move and resize with the mouse

PIXEL To use pixel coordinates instead of Text coordinates.

UPDATE This control may be updated from TDialog:Update() METHOD

CANCEL Using this clause you may bypass any current VALID clause and cancel the entire DialogBox.

See also: BtnBmp


CheckBox

Creating a CheckBox from source code

@ <nRow>, <nCol> CHECKBOX [ <oCbx> VAR ] <lVar> ;

[ PROMPT <cCaption> ] ;

[ OF | WINDOW | DIALOG <oWnd> ] ;

[ SIZE <nWidth>, <nHeight> ] ;

[ HELPID | HELP ID <nHelpId> ] ;

[ FONT <oFont> ] ;

[ ON CLICK | ON CHANGE <uClick> ] ;

[ VALID <ValidFunc> ] ;

[ COLOR | COLORS <nClrFore>;

[,<nClrBack>] ];

[ DESIGN ] ;

[ PIXEL ] ;

[ MESSAGE <cMsg> ] ;

[ UPDATE ] ;

[ WHEN <WhenFunc> ]

Using a CheckBox from a resource Dialog Box

REDEFINE CHECKBOX [ <oCbx> VAR ] <lVar> ;

[ ID <nId> ] ;

[ OF | WINDOW | DIALOG <oWnd> ] ;

[ HELPID | HELP ID <nHelpId> ] ;

[ ON CLICK | ON CHANGE <uClick> ];

[ VALID <ValidFunc> ];

[ COLOR | COLORS <nClrFore>;

[,<nClrBack>] ] ;

[ MESSAGE <cMsg> ] ;

[ UPDATE ] ;

[WHEN <uWhen> ]

<nRow>, <nCol> The coordinates of the CheckBox. They mimic text mode coordinates.

<oCbx> A reference to the CheckBox Object.

<lVar> The logical variable to be managed by the CheckBox.

<cCaption> The label of the CheckBox

<oWnd> The container window of the CheckBox.

<nWidth>, <nHeight> The dimensions of the CheckBox in pixels.

<nHelpId> The help topic value of the CheckBox.

<oFont> A reference to the Font Object to be used with the CheckBox.

<uClick> An action to be performed when the CheckBox changes.

<ValidFunc> An expression or function to be validated when the CheckBox loses its focus.

<nClrFore> Foreground color as a RGB number, or as a xBase string

<nClrBack> Background color as a RGB number

<cMsg> The associated message of this control.

<WhenFunc>, <uWhen> When expression code block.

<nId> The numeric resource identifier of the Control.

CLAUSES

DESIGN Allows the user to move and resize with the mouse

PIXEL To use pixel coordinates instead of Text coordinates.

UPDATE This control may be updated from TDialog:Update() METHOD


Clipboard

Creating a ClipBoard Object

DEFINE CLIPBOARD <oClp> ;

[ FORMAT TEXT | OEMTEXT | BITMAP | DIF ] ;

[ OF <oWnd> ]

ACTIVATE CLIPBOARD <oClp>

<oClp> A reference to the Clipboard Object.

<oWnd> The Window which is managing the Clipboard.

<cText> The Text to place at the Clipboard.

CLAUSES

TEXT

OEMTEXT Normal Text.

BITMAP Not implemented yet.

DIF Not implemented yet.


ComboBox

Creating a ComboBox from source code

@ <nRow>, <nCol> COMBOBOX [ <oCbx> VAR ] <cVar> ;

[ ITEMS | PROMPTS <aItems> ] ;

[ SIZE <nWidth>, <nHeight> ] ;

[ OF | WINDOW | DIALOG <oWnd> ] ;

[ HELPID | HELP ID <nHelpId> ] ;

[ ON CHANGE <uChange> ] ;

[ VALID <uValid> ] ;

[ COLOR | COLORS <nClrText>;

[,<nClrBack>] ] ;

[ PIXEL ] ;

[ FONT <oFont> ] ;

[ UPDATE ] ;

[ MESSAGE <cMsg> ] ;

[ WHEN <uWhen> ] ;

[ DESIGN ] ;

[ BITMAPS <acBitmaps> ] ;

[ ON DRAWITEM <uBmpSelect> ] ;

[ STYLE <nStyle> ];

[ PICTURE <cPicture> ];

[ ON EDIT CHANGE <uEChange> ]

Creating a ComboBox from resources

REDEFINE COMBOBOX [ <oCbx> VAR ] <cVar> ;

[ ITEMS | PROMPTS <aItems> ] ;

[ ID <nId> ] ;

[ OF | WINDOW | DIALOG <oWnd> ] ;

[ HELPID | HELP ID <nHelpId> ] ;

[ ON CHANGE <uChange> ] ;

[ VALID <ValidFunc> ] ;

[ COLOR | COLORS <nClrText>;

[,<nClrBack>] ] ;

[ UPDATE ] ;

[ MESSAGE <cMsg> ] ;

[ WHEN <uWhen> ] ;

[ BITMAPS <acBitmaps> ] ;

[ ON DRAWITEM <uBmpSelect> ] ;

[ STYLE <nStyle> ] ;

[ PICTURE <cPicture> ];

[ ON EDIT CHANGE <uEChange> ]

<nRow>, <nCol> The coordinates of the Button. They mimic text mode coordinates.

<oCbx> A reference to the ComboBox Object.

<cVar> A character variable which keeps the actual item selected in the ComboBox.

<aItems> The items showed on the ComboBox.

<nWidth>,<nHeight> The dimensions of the ComboBox in pixels.

<oWnd> The container window of the ComboBox.

<nHelpId> The help topic numeric identifier of the control.

<uChange> An action to be performed every time the selected item changes.

<cMsg> The associated message of this control.

<ValidFunc> An expression to validate when the control is going to lose the focus.

<nClrText> Foreground color as a RGB number, or as a xBase string.

<nClrBack> Background color defined as nClrText.

<oFont> A reference to the Font Object to be used with the Combobox.

<WhenFunc> When expression code block.

<nId> The numeric resource identifier of the Control.

<cBitmaps> A list of the bitmaps files or resources to use on a ownerdraw ComboBox.

<uBmpSelect> A codeblock to select which bitmap to paint on a ownerdraw ComboBox. By default, it uses the corresponding index in the bitmaps list.

<nStyle> To specifiy a dropdown ComboBox style. Use: STYLE CBS_DROPDOWN

<cPicture> The picture to use for the contained oGet DATA when using a dropdown ComBoBox, if the STYLE CBS_DROPDOWN has been specified.

<uEChange> An expression to be evaluated when the oGet DATA has changed if the STYLE CBS_DROPDOWN has been specified.

CLAUSES

PIXEL To use pixel coordinates instead of Text coordinates.

UPDATE This control may be updated from TDialog:Update() METHOD.

DESIGN Allows the user to move and resize with the mouse.


Cursor

Creating a cursor from resources

DEFINE CURSOR <oCursor> ;

[ RESOURCE | RESNAME | NAME <cResName> ] ;

[ ARROW | ICON | SIZENS | SIZEWE | SIZENWSE,;

SIZENESW | IBEAM | CROSS | SIZE | UPARROW | WAIT | HAND ]

<oCursor> A reference to the cursor object

<cResName> A string with the name of the cursor resource name. It may also be a numeric identifier.

CLAUSES

ARROW Arrow design

ICON Icon design

SIZENS North-South arrow design

SIZEWE West-east arrow design

SIZENWSE Nort-South & West-east arrow design

SIZENESW North-East & South-west arrow design

IBEAM Ibeam design

CROSS Cross design

SIZE Size adjustment design

UPARROW Up arrow design

WAIT Hour-glass design

HAND Hand design


DataBase

The benefits of Fivewin database object is that you do not need to create temporal variables for every field you need to manage. Simple crete the database object and then you only need that variable to hold all the field tables. If the database has a field name 'Code' for exmple, then your database object will also have a 'Code' data

To create a FiveWin TDataBase object

SELECT cAlias

DATABASE <Odbf>

Consult the Fivewin classes guide to learn more about Database objects


DDE

Defining a new DDE connection

DEFINE [ DDE | LINK ] <oDde> ;

[ SERVICE <cService> ] ;

[ TOPIC <cTopic> ] ;

[ ITEM <cItem> ] ;

[ ACTION <uAction> ] ;

[ VALID <uEnd> ]

Activating the DDE

ACTIVATE [ DDE | LINK ] <oDde>

Deactivating the DDE

DEACTIVATE [ DDE | LINK ] <oDde>

Ending the connection

RELEASE [ DDE | LINK ] <oDde>

<oDde> A reference to the DDE Object.

<cService> The service which establishes the connection.

<cTopic> The topic which establishes the connection.

<cItem> The item which establishes the connection.

<uAction> The action to perform once the connection is established.

<uEnd> An action to execute when the DDE is finished.


Dialogs

DialogBox creation from source code and redefinition for resources

DEFINE DIALOG <oDlg> ;

[ NAME | RESNAME | RESOURCE <cResName> ] ;

[ TITLE <cTitle> ] ;

[ FROM <nTop>, <nLeft> TO <nBottom>, <nRight>] ;

[ SIZE <nWidth>, <nHeight> ];

[ LIBRARY | DLL <hResources> ] ;

[ VBX ] ;

[ STYLE <nStyle> ] ;

[ COLOR | COLORS <nClrText> [,<nClrBack> ] ] ;

[ BRUSH <oBrush> ] ;

[ WINDOW | DIALOG | OF <oWnd> ] ;

[ PIXEL ] ;

[ ICON <oIco> ] ;

[ FONT <oFont> ] ;

[ HELP | HELPID <nHelpId> ]

Making the DialogBox work

ACTIVATE DIALOG <oDlg> ;

[ CENTER | CENTERED ] ;

[ NOWAIT | NOMODAL ] ;

[ WHEN <uWhen> ] ;

[ VALID <uValid> ] ;

[ ON [ LEFT ] CLICK <uClick> ] ;

[ ON INIT <uInit> ] ;

[ ON MOVE <uMoved> ] ;

[ ON PAINT <uPaint> ] ;

[ ON RIGHT CLICK <uRClicked> ]

<oDlg> The variable that is going to hold the DialogBox object. It is a 'reference' to the DialogBox object.

<cResName> The name of the DialogBox inside resource. The resource may be stored in a .RC file or in a .DLL file. Normally you use the 'Rename' option from a resource editor to give a name to the resource element.

<cTitle> The title of the DialogBox. You may also change the title of a resource DialogBox. This means that you may use the same DialogBox for different purposes by just changing its title.

<nTop>, <nLeft> The coordinates of the DialogBox when creating the DialogBox from source code.

<nRight> <nBottom> The right and bottom coordinates of the DialogBox.

<nWidth><nHeight> The width and height dimensions of the DialogBox.

<hResources> An optional handle to a resource DLL. This is useful when using several DLLs at the same time that hold different resources. By default this handle is the application handle (when using .RC) or the handle of the DLL when using SET RESOURCES TO...

<nStyle> An optional DialogBox style. There are several samples in the SAMPLES\ subdirectory showing you how to manipulate this value. If you are using a DialogBox from a resource then you have to select the style from inside the resource editor.

<nClrText>, <nClrBack> The fore and back colors of the DialogBox.

<oBrush> An optional brush to use to fill the surface of the DialogBox.

<oWnd> An optional container object of the DialogBox. By default we use the window that is currently active. If you want to show DialogBoxes control messages on the bottom line of the screen you have to specify its container.

<oIco> An optional ICON to show when the DialogBox has been minimized.

<oFont> An optional Font to use for all the DialogBoxes.

<uWhen> WHEN clause that permits the DialogBox to start executing.

<uValid> VALID clause to control the ending of the DialogBox.

<nHelpId> The Help topic identifier of the dialog.

<uClick> Optional action to perform when the left mouse button is clicked over the DialogBox surface. Three parameters: nRow, nCol, nFlags are automatically supplied:

nRow The row position (in pixels) where the mouse was when it was clicked.

nCol The col position (in pixels) where the mouse was when it was clicked.

Nflags A numeric flag which contains information about special keys being pressed at the same time: (values are'ORed') Value Description

MK_CONTROL Set if CTRL key is down.

MK_MBUTTON Set if middle button is down.

MK_RBUTTON Set if right button is down.

MK_SHIFT Set if SHIFT key is down.

#define MK_LBUTTON 0x0001

#define MK_RBUTTON 0x0002

#define MK_CONTROL 0x0008

#define MK_MBUTTON 0x0010

You may inspect them using FiveWin lAnd() function:

if lAnd( nFlags, MK_CONTROL )

If lAnd( nFlags, MK_SHIFT, MK_CONTROL )

...

<uInit> An optional action to perform when the DialogBox is created but not shown on the screen. In this situation the DialogBox behaves like a Window, and we may do all kind of operations as we do with a window, (like placing a ButtonBar on it!)

<uMoved> An optional action to be performed when the DialogBox is moved.

<uPaint> An optional action to be performed when the DialogBox has just been painted.

<uRClicked> An optional action to be performed when the right mouse button has been clicked on the DialogBox surface. You can use the same three parameters as in <uClick>.

CLAUSES

VBX You may specify this when using a VBX control in the DialogBox.

PIXEL When you want the DialogBox coordinates (creating the DialogBox from source code) to be in pixels.

CENTER CENTERED If you want the DialogBox to appear centered on the screen.

NOWAIT NOMODAL If the DialogBox has to behave NonModal. NonModal means that other DialogBoxes may be working at the same time! NonModal programming requires some special care:

Warning:

·Take care of local variables: If you are using some locals then remember you will go out of the scope of the function where the DialogBox nonmodal has been created and this may cause problems (only if you don't remember it). Clipper works perfectly in these circumstances as it keeps 'live references' of the local variables inside the codeblocks. But only these will be 'alive' out of the function.

· The same DialogBox may be executed several times. Be aware of your DBF management. In these circums- tances your computer is like a NetWork! because a DBF may be opened several times. It is a good idea to start learning NetWork programming -it is really easy!-

· Normally we recommend that you not develop NonModal applications for novice Windows-users. As soon as your clients get more and more used to Windows, NonModal programming is highly recommended. See MDI programming (in this documentation) for a very elegant and powerful NonModal programming style.


DLL

Defining a external DLL function to be called at RunTime

DLL [STATIC] FUNCTION <FuncName> ( ;[ <Param1> AS <Type1> ] ;

[ <ParamN> AS <TypeN> ] ) ;

AS <return> [PASCAL] [ FROM <SymName> ] LIB <DllName>

To access a 32 bits DLL function

DLL32 [STATIC] FUNCTION <FuncName> ( ;[ <Param1> AS <Type1> ] ;

[ <ParamN> AS <TypeN> ] ) ;

AS <return> [PASCAL] [ FROM <SymName> ] LIB <DllName>

FiveWin lets you declare an external DLL function to be called at RunTime by its own name! See DllCall.prg example.

<FuncName> The name of the DLL function. Remember Clipper only uses 10 characters maximum length.

<Param1> Name of a parameter.

Length in bytes

<Type>,<return> BYTE, CHAR 1

WORD, BOOL, HANDLE, HWND, HDC 2

LONG, STRING, LPSTR, PTR 4

DOUBLE 8

<SymName> The name of the DLL function to execute. By default the same DLL FUNCTION <name> is used.

<DllName> Name of the DLL.

CLAUSES

FROM To specify a different DLL function name to access. Please review SOURCE\WINAPI\* .prg code samples.

We recommend to develop a C language based connection functions when you are going to develop an intensively work with some DLLs. See "using Windows API". Examples:

Calling SndPlaySound() at RunTime:

#include "FiveWin.ch"

function Main()

SndPlaySound( "tada.wav", 0 )

return

DLL FUNCTION SndPlaySound( cFile AS LPSTR, nType AS WORD );

AS BOOL PASCAL LIB "MMSYSTEM.DLL"

Designing the same DLL connection using C language:

#include <WinTen.h>

#include <Windows.h>

#include <MMSystem.h>

#include <ClipApi.h>

CLIPPER SNDPLAYSOU() // ND()

{

_retl( sndPlaySound( _parc( 1 ), _parni( 2 ) ) );

}

In this situation it is necessary to use a specific LIB so the linker will know how the DLL connection must be done at RunTime. Example:

TEST.DLL // Is a commercial DLL we are going to use

IMPDEF.EXE TEST.DEF TEST.DLL // IMPDEF.EXE is a tool Microsoft and

// Borland provides

Now, edit TEST.DEF -which it is an ascii file- and rename the symbols with 10 characters or less with an underscore:

LESS10 ---> _LESS10

Then do:

IMPLIB.EXE TEST.LIB TEST.DEF

When linking use that .LIB !

Review our \WinApi directory C -only registered users- source code to see a lot of examples of doing this.

Warning: SndPlaySound() is already built inside FiveWin.lib. It has been used just in this example for learning purposes.


Folders

reating a folder from source code

@ <nRow>, <nCol> FOLDER [<oFolder>] ;

[ OF | WINDOW | DIALOG <oWnd> ] ;

[ PROMPT | PROMPTS | ITEMS <cPrompt,...> ] ;

[ DIALOG | DIALOGS | PAGE | PAGES <cDlgName1> [,<cDlgNameN>] ] [ PIXEL ] ;

[ DESIGN ] ;

[ COLOR | COLORS <nClrFore> [,<nClrBack>] ] ;

[ OPTION <nOption> ] ;

[ SIZE <nWidth>, <nHeight> ] ;

[ MESSAGE <cMsg> ]

[ ADJUST];

[ FONT <oFont> ]

Creating a folder from resources

REDEFINE FOLDER [<oFolder>] ;

[ ID <nId> ] ;

[ OF | WINDOW | DIALOG <oWnd> ] ;

[ PROMPT | PROMPTS | ITEMS <cPrompt,...> ] ;

[ DIALOG | DIALOGS | PAGE | PAGES <cDlgName1> [,<cDlgNameN>] ;

[ COLOR | COLORS <nClrFore> [,<nClrBack>] ] ;

[ OPTION <nOption> ] ;

[ ON CHANGE <uChange> ]

[ ADJUST ]

<nRow>, <nCol> The coordinates where to locate the folder control (only from source code, not from resources).

<oFolder> A reference to the folder object just created.

<oWnd> The container object of the folder control.

<cPrompt,...> A list with the text to show as each page prompts.

<cDlgName1,...> A list with the resources names of the DialogBoxes to manage.

<nClrFore> The color to display the prompts text.

<nClrBack> The color to fill the folder surface.

<nOption> An optional initial option to use different from 1.

<nWidth>, <nHeight> The dimensions of the folder control.

<cMsg> An optional message to display on its container MsgBar if defined.

<nId> The numeric resource identifier of the control.

<oFont> An optional font object to use for the folder.

<uChange> An action to be performed when changing the folder selected page.

CLAUSES

PIXEL To use pixel coordinates instead of text coordinates.

DESIGN Allows the user to interactively move and resize the control.

ADJUST To use the entire folder width to calculate the pages tabs dimensions.

FONT To specify an optional font to be used for the folder.


Fonts

Defining a font

DEFINE FONT <oFont> ;

[ NAME <cName> ] ;

[ SIZE <nWidth>, <nHeight> ] ;

[ FROM USER ];

[ BOLD ] ;

[ ITALIC ] ;

[ UNDERLINE ] ;

[ WEIGHT <nWeight> ] ;

[ OF <oDevice> ] ;

[ NESCAPEMENT <nEscapement> ]

ACTIVATE FONT <oFont>

DEACTIVATE FONT <oFont>

RELEASE FONT <oFont>

SET FONT ;

[ OF <oWnd> ] ;

[ TO <oFont> ]

<oFont> A reference to the Font Object.

<cName> The name of the font. Example: Arial, Roman, etc...

<nWidth>, <nHeight> Dimensions of the font.

<oWnd> A reference to the Window container.

<oDevice> The device owner of the font.

<nWeight> The weight of the font.

<nEscapement> The escapement of the font.

CLAUSES

FROM USER Displays the Font selection Dialog Box.

BOLD To create the font with bold feature.

ITALIC To create the font with italic feature.

UNDERLINE To create the font with underline feature.


GETs

Creating a GET from source code

@ <nRow>, <nCol> GET [ <oGet> VAR ] <uVar> ;

[ OF | WINDOW | DIALOG <oWnd> ] ;

[ MULTILINE | MEMO | TEXT ];

[ COLOR | COLORS <nClrFore>;[,<nClrBack>] ] ;

[ SIZE <nWidth>, <nHeight> ];

[ FONT <oFont> ] ;

[ HSCROLL ] ;

[ CURSOR <oCursor> ] ;

[ PIXEL ] ;

[ MESSAGE <cMsg> ] ;

[ UPDATE ] ;

[ WHEN <uWhen> ] ;

[ CENTER | CENTERED> ];

[ RIGHT ] ;

[ READONLY | NO MODIFY ] ;

[ VALID <uValid> ] ;

[ ON CHANGE <uChange> ] ;

[ DESIGN ]

For editing Memos

@ <nRow>, <nCol> GET [ <oGet> VAR <uVar> ] ;

[ OF | WINDOW | DIALOG <oWnd> ] ;

[ PICTURE <cPict> ];

[ VALID <ValidFunc> ] ;

[ COLOR | COLORS <nClrFore>;[,<nClrBack>] ] ;

[ SIZE <nWidth>, <nHeight> ] ;

[ FONT <oFont> ] ;

[ DESIGN ] ;

[ CURSOR <oCursor> ] ;

[ PIXEL ] ;

[ MESSAGE <cMsg> ] ;

[ UPDATE ] ;

[ WHEN <WhenFunc> ] ;

[ CENTER | CENTERED ] ;

[ RIGHT ] ;

[ ON CHANGE <uChange> ] ;

[ READONLY | NO MODIFY ] ;

[ PASSWORD];

[ NO BORDER | NOBORDER ];

[ HELPID | HELP ID <nHelpId> ]

@ <nRow>, <nCol> GET [ <oGet> VAR <uVar> ] ;

[ OF | WINDOW | DIALOG <oWnd> ] ;

[ PICTURE <cPict> ];

[ VALID <ValidFunc> ] ;

[ COLOR | COLORS <nClrFore>;[,<nClrBack>] ] ;

[ SIZE <nWidth>, <nHeight> ] ;

[ FONT <oFont> ] ;

[ DESIGN ] ;

[ CURSOR <oCursor> ] ;

[ PIXEL ] ;

[ MESSAGE <cMsg> ] ;

[ UPDATE ] ;

[ WHEN <WhenFunc> ] ;

[ CENTER | CENTERED ] ;

[ RIGHT ] ;

[ ON CHANGE <uChange> ] ;

[ READONLY | NO MODIFY ] ;

[ HELPID | HELP ID <nHelpId> ];

[ SPINNER [ ON UP <SpnUp> ] [ ON DOWN < SpnDn> ] [ MIN <Min> ] [ MAX <Max> ]

Using a GET from a resource Dialog Box

REDEFINE GET [ <oGet> VAR ] <uVar> ;

[ ID <nId> ] ;

[ OF | WINDOW | DIALOG <oWnd> ] ;

[ HELPID | HELP ID <nHelpId> ] ;

[ VALID <ValidFunc> ] ;

[ PICTURE <cPict> ] ;

[ COLOR | COLORS <nClrFore>; [ ,<nClrBack>] ] ;

[ FONT <oFont> ] ;

[ CURSOR <oCursor> ] ;

[ MESSAGE <cMsg> ] ;

[ UPDATE ] ;

[ WHEN <WhenFunc> ] ;

[ ON CHANGE <uChange> ] ;

[ READONLY | NO MODIFY ] ;

[ SPINNER [ ON UP <SpnUp> ] [ ON DOWN < SpnDn> ] [ MIN <Min> ] [ MAX <Max> ]

For editing Memos

REDEFINE GET [ <oGet> VAR ] <uVar> ;

[ MULTILINE | MEMO | TEXT ] ;

[ ID <nId> ] ;

[ OF | WINDOW | DIALOG <oWnd> ] ;

[ HELPID | HELP ID <nHelpId> ] ;

[ COLOR | COLORS <nClrFore> [,<nClrBack>] ] ;

[ FONT <oFont> ] ;

[ CURSOR <oCursor> ] ;

[ MESSAGE <cMsg> ] ;

[ UPDATE ] ;

[ WHEN <WhenFunc> ] ;

[ READONLY | NO MODIFY> ] ;

[ VALID <ValidFunc> ] ;

[ ON CHANGE <uChange> ];

<nRow>, <nCol> The coordinates of the GET. We simulate Text coordinates.

<oGet> A reference to the GET Object.

<uVar> The variable which the GET Object is manipulating.

<oWnd> The container window of the GET.

<cPict> Typical xBase PICTURE clause.

<ValidFunc> Validating expression or function. The same as in MsDos.

<WhenFunc> When Clause. Not available yet!

<cColor> The color of the GET. Not available yet!

<nWidth>, <nHeight> The dimensions in pixels of the GET.

<oFont> A reference to the Font Object to be used with the GET.

<oCursor> A reference to the Cursor Object to dispay over this control.

<cMsg> The associated message of this control.

<nId> The numeric resource identifier of the Control.

<nHelpId> Help topic identifier for GETs from resources.

<nClrFore> Foreground color as a RGB number, or as a xBase string Background

<nClrBack> color as a RGB number

<SpnUp> An action to perform when the GET spinner, if defined, is up pressed.

<SpnDn> An action to perform when the GET spinner, if defined, is down pressed.

<Min> The minimum value of the GET spinner, if defined.

<Max> The maximum value of the GET spinner, if defined.

<uChange> An action to be performed when the Get changes.

CLAUSES

MULTILINE, MEMO, TEXT To use a multiple lines GET control to allow memo editing.

UPDATE This control may be updated from TDialog:Update() METHOD

CENTER If the GET containts has to appear centered

RIGHT If the GET containts has to appear right justified. Important: In order to right justify a GET from a DialogBox, it has to be defined at the resource as MultiLine and right and has to use the default font!

PIXEL To use pixel coordinates instead of Text coordinates.

PASSWORD Enter as Password.

DESIGN Allows the user to move and resize with the mouse

HSCROLL Horizontal Scroll

READ ONLY Disables editing in this control.

NO MODIFY To set a read only GET.

NO BORDER, NOBORDER To avoid the GET border.

HELP ID, HELPID An optional Help Id to request topic help.

SPINNER To show a right placed spinner.

NO VSCROLL To avoid a vertical scrollbar.

ON UP To specify an action to perform when up clicking the spinner.

ON DOWN To specify an action to perform when down clicking the spinner.

MIN The minimum value of the spinner.

MAX The maximum value of the spinner.


Group

@ <nTop> . <nLeft> [ GROUP <oGroup> ] TO <nBottom>, <nRight> ;

[ LABEL | PROMPT <cLabel> ];

[ COLOR <cClrFore> [, <nClrBack> ] ];

[ PIXEL ];

[ DESIGN ]

REDEFINE GROUP [ <oGroup> ];

[ LABEL | PROMPT <cLabel> ];

[ ID <nId> ];

[ OF | WINDOW | DIALOG <oWnd> ];

[ COLOR <cClrFore> [, <nClrBack> ] ]

<nTop> , <nLeft> To specify the top and left coordinates.

<nRight>, <nBottom> To specify the right and bottom coordinates.

<cLabel> The caption of the group.

<nClrBack> The background color of the group.

<cClrFore> The foreground color of the group.

<oGroup> The variable to containt the object.

<oWnd> The window or dialogbox container of this control.

<nId> The resource identifier for this control.

CLAUSES

PIXEL To specify pixel corrdinates.

DESIGN To drag around the control using the mouse.


HELP

Sets the default HELP file of the application

SET HELP TO <cHLPFile>

SET HELP TOPIC TO <cTopic>

FiveWin lets you assign a HLP file as the default HELP file of your application so it will be automatically managed from the Fivewin extended help functions. This functionality complement the standard WinApi help functions.


Icons

Creating an Icon control from source code

@ <nRow>, <nCol> ICON [ <oIcon> ] ;

[ NAME | RESOURCE | RESNAME <cResName> ] ;

[ FILE | FILENAME | DISK <cIcoFile> ] ;

[ BORDER ] ;

[ COLOR | COLORS <nClrFore>;[,<nClrBack>] ] ;

[ ON CLICK <uClick> ] ;

[ OF | WINDOW | DIALOG <oWnd> ];

[ UPDATE ] ;

[ WHEN <WhenFunc> ]

Redefing an Icon from Resources

REDEFINE ICON <oIcon>

[ ID <nId> ] ;

[ NAME | RESOURCE | RESNAME <cResName> ] ;

[ FILE | FILENAME | DISK <cIcoFile> ] ;

[ ON CLICK <uClick> ] ;

[ OF | WINDOW | DIALOG <oWnd> ] ;

[ UPDATE ] ;

[ WHEN <WhenFunc> ]

DEFINE ICON <oIcon>

[ NAME | RESOURCE | RESNAME <cResname> ];

[ FILE | FILENAME | DISK <cIcoFile> ];

[ WHEN <WhenFunc> ]

<nRow>, <nCol> Are the coordinates on the screen. We simulate text coordinates.

<oIcon> Is a reference to the Icon Object.

<cResName> Is the name of the icon resource if we are loading the icon from a RC, RES or a DLL.

<cIcoFile> Is the name of a ICO file if we are loading the ICO directly from disk.

<uClick> Is the action to be performed when the mouse clicks over the icon.

<oWnd> Is the container Object of the Icon.

<WhenFunc> An expression to evaluate in order to determine if the control is available or not.

<nClrFore> Foreground color as a RGB number, or as a xBase string

<nClrBack> Background color as a RGB number

Defining an Icon without showing it

DEFINE ICON <oIcon> ;

[ NAME | RESOURCE | RESNAME <cResName> ] ;

[ FILE | FILENAME | DISK <cIcoFile> ]

[ WHEN <WhenFunc> ]

<oIcon> Is a reference to the Icon Object.

<cResName> Is the name of the icon resource if we are loading the icon from a RC, RES or a DLL.

<cIcoFile> Is the name of a ICO file if we are loading the ICO directly from disk.

CLAUSES

UPDATE Indicates if this control has to be updated when doing a <oDlg>: Update() of its container.

BORDER Create a border arround the control.


Image

@ <nRow>, <nCol> IMAGE [<oImg> ];

[ NAME | RESNAME | RESOURCE <cResName> ];

[ FILE | FILENAME | DISK <cBmpFile> ];

[ NO BORDER | NOBORDER ];

[ SIZE <nWidth>, <nHeight> ];

[ OF | WINDOW | DIALOG <oWnd> ];

[ ON CLICK | ON LEFT CLICK <uLclick> ];

[ ON RIGHT CLICK <uRclick> ];

[ SCROLL ];

[ ADJUST ];

[ CURSOR <oCursor> ];

[ PIXEL];

[ MESSAGE <cMsg> ];

[ UPDATE ];

[ WHEN <uWhen> ];

[ VALID <uValid> ];

[ DESIGN ]

REDEFINE IMAGE [ <oImg> ];

[ ID <nId> ];

[ OF | WINDOW | DIALOG <oWnd> ];

[ NAME | RESNAME | RESOURCE <cResName> ];

[ FILE | FILENAME | DISK <cBmpFile> ];

[ ON CLICK | ON LEFT CLICK <uLclick> ];

[ ON RIGHT CLICK <uRclick> ];

[ SCROLL ];

[ ADJUST ];

[ CURSOR <oCursor> ];

[ MESSAGE <cMsg> ];

[ UPDATE ]

[ WHEN <uWhen> ];

[ VALID <uValid> ];

<uValid> Code Block for VALID clause.

<cMsg> The text for the default message on the MsgBar.

<uWhen> Code Block for WHEN clause.

<oCursor> An optional cursor object to use.

<uLClick> An optional action to perform when the mouse is left clicked.

<nWidth>, <nHeight> The width and height dimensions of the control.

<cResName> The resource name for the image to display.

<nId> The resource identifier for this control.

<uRClick> An optional action to perform when the mouse is right clicked.

<cBmpFile> The name of the image file to display.

<oWnd> The window or dialog container object of this control.

<oImg> The variable to hold this object.

CLAUSES

SCROLL To automatically show both scrollbars on the control.

ADJUST To adjust the image to the control dimensions.

PIXEL To specify pixel coordinates.

UPDATE To repaint this control when its container gets :Updated()

DESIGN To drag around this control using the mouse.

See also: Bitmap


InI

Managing an INI file

INI <oIni> ;

[ FILE | FILENAME | DISK <cIniFile> ]

GET <uVar> ;

[ SECTION <cSection> ] ;

[ ENTRY <cEntry> ] ;

[ DEFAULT <uDefault> ] ;

[ OF | INI <oIni> ]

SET ;

[ SECTION <cSection> ] ;

[ ENTRY <cEntry> ] ;

[ TO <uVal> ] ;

[ OF | INI <oIni> ]

ENDINI

<oIni> A reference to the INI Object.

<cIniFile> The name of the INI file.

<uVar> A variable with the value loaded from the INI file. This value gets automatically converted to the type of the variable. So it is important to properly initialize the variable before loading its value.

<cEntry> Entry=Value

<cSection> [SECTION] -Typical formats inside .INI-

<uDefault> A default value to use when that Entry is not found.

<uVal> The new value to set.


ListBox

Creating a ListBox from source code

@ <nRow>, <nCol> LISTBOX [ <oLbx> VAR ] <cnVar> ;

[ ITEMS | PROMPTS <aList> ] ;

[ SIZE <nWidth>, <nHeight> ] ;

[ ON CHANGE <uChange> ] ;

[ ON [ LEFT ] DBLCLICK <uLDblClick> ] ;

[ OF | WINDOW | DIALOG <oWnd> ] ;

[ VALID <uValid> ] ;

[ COLOR | COLORS <nClrFore> [,<nClrBack>] ] ;

[ PIXEL ] ;

[ DESIGN ] ;

[ FONT <oFont> ] ;

[ MESSAGE <cMsg> ] ;

[ UPDATE ] ;

[ WHEN <uWhen> ]

[ BITMAPS <acBitmaps> ] ;

[ ON DRAWITEM <uBmpSelect> ] ;

[ MULTI | MULTIPLE | MULTISEL ] ;

[ SORT ]

Creating a ListBox from resources

REDEFINE LISTBOX [ <oLbx> VAR ] <cnVar> ;

[ ITEMS | PROMPTS <aItems> ] ;

[ FILES | FILESPEC <cFileSpec> ] ;

[ ID <nId> ] ;

[ ON CHANGE <uChange> ] ;

[ ON [ LEFT ] DBLCLICK <uLDblClick> ] ;

[ OF | WINDOW | DIALOG <oWnd> ] ;

[ HELPID | HELP ID <nHelpId> ] ;

[ BITMAPS [ SIZE <nSize> ] ] ;

[ VALID <uValid> ] ;

[ COLOR | COLORS <nClrFore> [,<nClrBack>] ] ;

[ MESSAGE <cMsg> ] ;

[ UPDATE ] ;

[ WHEN <uWhen> ]

[ BITMAPS <aBitmaps> ] ;

[ ON DRAWITEM <uBmpSelect> ]

<nRow>, <nCol> The coordinates of the ListBox. They mimic text mode coordinates.

<oLbx> A reference to the ListBox object.

<cnVar> A Clipper variable, string or numeric, where FiveWin will automatically select the item selected in the ListBox.

<aList> An Clipper array of strings, used to fill the ListBox items.

<nWidth>, <nHeight> The dimensions of the ListBox in pixels.

<uChange> A codeblock to evaluate everytime a item of the ListBox is selected.

<uLDblClick> A codeblock to evaluate when the user left double clicks the mouse over the listbox.

<oWnd> A reference to the container object of the ListBox, normally a window or a DialogBox.

<uValid> A codeblock that holds the VALID clause of the ListBox.

<nClrFore> The color of the text of the ListBox items.

<nClrBack> The color of the background of the ListBox items.

<oFont> An optional font object to use when painting the ListBox items.

<cMsg> The message to show at the messageBar of the ListBox container if defined (a window or a DialogBox normally).

<uWhen> A codeblock that holds the WHEN clause of the ListBox.

<cFileSpec> A 'mask' to use to automatically show files from disk. i.e.: "*.*"

<nId> The control numeric identifier when managing resources.

<nHelpId> The help identifier for the ListBox.

<nSize> An optional size for the bitmaps used when doing a ownerdraw ListBox.

<acBitmaps> An optional array of bitmaps names when doing a ownerdraw ListBox.

<uBmpSelect> A codeblock to evaluate everytime a bitmap is going to be draw on a ownerdraw ListBox. This codeblock lets select the index of different bitmap to paint.

CLAUSES

PIXEL To specify that <nRow> and <nCol> must be trated as pixels,and not simulated as MsDos text rows and cols.

DESIGN To let the user move around the control with the mouse.

UPDATE To specify that this control should be repainted (:Refresh()) when issuing a <oDlg>:Update() of its container DialogBox.

MULTI | MULTIPLE | MULTISEL Alows Multiple selection.

BITMAPS To specify an array of bitmaps names to be used on a ownerdraw ListBox.

ON DRAWITEM To specify a certain bitmap index to paint on a ownerdraw ListBox.

SORT To show the ListBox containts sorted by name.


Mail

DEFINE MAIL [ <oMail> ];

[ SUBJECT <cSubject> ];

[ TEXT <cText> ];

[ TYPE <cType> ];

[ DATE <dDate> ];

[ TIME <cTime> ];

[ CONVERSATION <cConversation> ]:

[ RECEIPT ];

[ FROM USER ];

[ FILES <cFilename1> ,<cDescript1>, <cFilenameN>, <cDescriptN> ] ];

[ ORIGIN <cOrigin> [ <cOriginAddress> ] ];

[ TO <cTarget1>, [ <cTargetAddress1> ] [ <cTargetN> [ <cTargetAddressN> ] ] ];

ACTIVATE MAIL <oMail>

SEND MAIL <oMail>

<oMail> The variable to hold this object.

<cTarget1>, <cTargetN> The list of targets names to receive the email.

<cTargetAddressN>,<cTargetAddress1>The list of targets email adresses to receive the

email.

<cFilename1> , <cFilenameN>,

<cDescript1>, <cDescriptN> The list of filenames to attach to the email.

The list of descriptions for each atached file.

<cConversation> The conversation ID.

<cText> The body text of the email.

<cType> The type of the message.

<cTime> The time for the email.

<dDate> The date foe the email.

<cSubject> The topic of the email.


MDI

See below for a full explanation about Windows MDI use.

Creating a MDI frame Window is done in a very similar way to a normal Window. The difference is just specify MDI.

DEFINE WINDOW <oWnd> ;

[ FROM <nTop>, <nLeft> TO <nBottom>, <nRight> ] ;

[ TITLE <cTitle> ] ;

[ STYLE <nStyle> ] ;

[ MENU <oMenu> ] ;

[ BRUSH <oBrush> ] ;

[ ICON <oIcon> ] ;

[ MDI ] ;

[ COLOR | COLORS <nClrFore> [,<nClrBack>] ] ;

[ VSCROLL | VERTICAL SCROLL ] ;

[ HSCROLL | HORIZONTAL SCROLL ] ;

[ MENUINFO <nMenuInfo> ] ;

[ [ BORDER ] <NONE | SINGLE> ] ;

[ OF <oParent> ];

[ PIXEL ]

ACTIVATE WINDOW <oWnd> ;

[ ICONIZED | NORMAL | MAXIMIZED> ] ;

[ ON [ LEFT ] CLICK <uLClick> ] ;

[ ON LBUTTONUP <uLButtonUp> ];

[ ON RIGHT CLICK <uRClick> ] ;

[ ON MOVE <uMove> ] ;

[ ON RESIZE <uResize> ] ;

[ ON PAINT <uPaint> ] ;

[ ON KEYDOWN <uKeyDown> ] ;

[ ON INIT <uInit> ] ;

[ ON UP <uUp> ] ;

[ ON DOWN <uDown> ] ;

[ ON PAGEUP <uPgUp> ] ;

[ ON PAGEDOWN <uPgDn> ] ;

[ ON LEFT <uLeft> ] ;

[ ON RIGHT <uRight> ] ;

[ ON PAGELEFT <uPgLeft> ] ;

[ ON PAGERIGHT <uPgRight> ] ;

[ ON DROPFILES <uDropFiles> ];

[ VALID <uValid> ]

See Window creating commands, as all the items are the same except:

MDI Specify that the main Window is going to be a MDI Window

<nMenuInfo> Is the position of the PopUp at the PullDown menu where Windows automatically reports which child Window is activated.

Activation Commands are the same as with a normal Window.

To create a ChildWindow of the main MDI Window, we do it again in a similar way as creating a Window:

DEFINE WINDOW [<oWnd>] ;

[ MDICHILD ] ;

[ FROM <nTop>, <nLeft> TO <nBottom>, <nRight> ] ;

[ TITLE <cTitle> ] ;

[ BRUSH <oBrush> ] ;

[ CURSOR <oCursor> ] ;

[ MENU <oMenu> ] ;

[ MENUINFO <nMenuInfo> ];

[ ICON <oIco> ] ;

[ OF <oParent> ] ;

[ VSCROLL | VERTICAL SCROLL ] ;

[ HSCROLL | HORIZONTAL SCROLL ] ;

[ COLOR | COLORS <nClrFore> [,<nClrBack>] ] ;

[ STYLE <nStyle> ] ;

[ HELPID | HELPID <nHelpId> ];

[ BORDER <NONE | SINGLE> ] ;

[ NOSYSMENU | NO SYSMENU> ] ;

[ NOCAPTION | NO CAPTION | NO TITLE> ] ;

[ NOICONIZE | NOMINIMIZE> ] ;

[ NOZOOM | NO ZOOM | NOMAXIMIZE | NO MAXIMIZE> ] ;[ PIXEL ]

ACTIVATE WINDOW <oWnd> ;

[ ICONIZED | NORMAL | MAXIMIZED> ] ;

[ ON [ LEFT ] CLICK <uLClick> ] ;

[ ON LBUTTONUP <uLButtonUp> ];

[ ON RIGHT CLICK <uRClick> ] ;

[ ON MOVE <uMove> ] ;

[ ON RESIZE <uResize> ] ;

[ ON PAINT <uPaint> ] ;

[ ON KEYDOWN <uKeyDown> ] ;

[ ON INIT <uInit> ] ;

[ ON UP <uUp> ] ;

[ ON DOWN <uDown> ] ;

[ ON PAGEUP <uPgUp> ] ;

[ ON PAGEDOWN <uPgDn> ] ;

[ ON LEFT <uLeft> ] ;

[ ON RIGHT <uRight> ] ;

[ ON PAGELEFT <uPgLeft> ] ;

[ ON PAGERIGHT <uPgRight> ] ;

[ ON DROPFILES <uDropFiles> ];

[ VALID <uValid> ]

<oWnd> Window Object container of the window

<uLClick> An action to be performed when the left button of the mouse is clicked over the Window.

<uRClick> An action to be performed when the right button of the mouse is clicked over the Window.

<uMove> An action to be performed every time the Window is moved.

<uResize> An action to be performed every time the Window is resized.

<uPaint> An action, generally drawing action, to be performed every time the Window is painted.

<uKeyDown> An action to be performed every a key is pressed being the Window focused.

<uInit> An action to be performed, generally some initialization, when the Window is being initialized.

<uUp> An action to be performed when the vertical scrollbar is upwards pressed.

<uDown> An action to be performed when the vertical scrollbar is downards pressed.

<uPgUp> An action to be performed when the vertical scrollbar has been pagedown clicked.

<uPgDn> An action to be performed when the vertical scrollbar has been pageup clicked.

<uLeft> An action to be performed when the horizontal scrollbar has been leftwards clicked.

<uRight> An action to be performed when the horizontal scrollbar has been rightwards clicked.

<uPgLeft> An action to be performed when the horizontal scrollbar has been pageleft clicked.

<uPgRight> An action to be performed when the horizontal scrollbar has been pageright clicked.

<uValid> An action to validate to let the window be closed.

<nTop> <nLeft>

<nBottom> <nRight> Window coordinates on screen. We simulate text coordinates.

<nStyle> Determines the characteristics of the window. These characteristics are define by the following constants (defined in WINAPI.CH):

Constant Purpose

WS_BORDER Window has a border.

WS_CAPTION Window has a title bar (implies the WS_BORDER style). This style cannot be used with the WS_DLGFRAME style.

WS_CHILD A child window. Cannot be used with the WS_POPUP style.

WS_CHILDWINDOW Same as the WS_CHILD style.

WS_CLIPCHILDREN Excludes the area occupied by child windows when drawing within the parent window. Used when creating the parent window.

WS_CLIPSIBLINGS Clips child windows relative to each other; that is, when a particular child window receives a paint message, the WS_CLIPSIBLINGS style clips all other overlapped child windows out of the region of the child window to be updated. (If WS_CLIPSIBLINGS is not specified and child windows overlap, it is possible, when drawing within the client area of a child window, to draw within the client area of a neighboring child window.) For use with the WS_CHILD style only.

WS_DISABLED Window will be initially disabled.

WS_DLGFRAME Defines a window with a double border but no title.

WS_GROUP Specifies the first control of a group of controls in which the user can move from one control to the next by using the arrow keys. All controls defined with the WS_GROUP style after the first control belong to the same group. The next control with the WS_GROUP style ends the style group and starts the next group (that is, one group ends where the next begins). Only dialog boxes use this style.

WS_HSCROLL Window has a horizontal scroll bar.

WS_MAXIMIZE Window should be of maximum size.

WS_MAXIMIZEBOX Creates a window that has a Maximize button.

WS_MINIMIZE Define window that is initially minimized. For use with the WS_OVERLAPPED Creates a window that has a Minimize button.

WS_OVERLAPPED Defines an overlapped window. An overlapped window has a title and a border.

WS_OVERLAPPEDWINDOW Creates an overlapped window having the WS_OVERLAPPED, WS_CAPTION, WS_SYSMENU, WS_THICKFRAME, WS_MINIMIZEBOX, and WS_MAXIMIZEBOX styles.

WS_POPUP Creates a pop-up window. Cannot be used with the WS_CHILD style.

WS_POPUPWINDOW Creates a pop-up window that has the WS_BORDER, WS_POPUP, and WS_SYSMENU styles. The WS_CAPTION style must be combined with the WS_POPUPWINDOW style to make the System menu visible.

WS_SYSMENU Creates a window that has a System-menu box in its title bar. Used only for windows with title bars.

WS_TABSTOP Specifies one of any number of controls through which the user can move by using the TAB key. The TAB key moves the user to the next control specified by the WS_TABSTOP style. Only dialog boxes use this style.

WS_THICKFRAME Creates a window with a thick frame that can be used to size the window.

WS_VISIBLE Creates a window that is initially visible. This applies to overlapped, child, and pop-up windows. For overlapped windows, the y parameter is used as a ShowWindow function parameter.

WS_VSCROLL Creates a window that has a vertical scroll bar.

Note: If this parameter is used it will override the values of the following parameters:

· cBorder

· lCaption

· lSysmenu

· lmin

· lMax

· lVScroll

· lHScroll

In order to combine several styes use the function nOr():

nOr( nStyle1, nStyle2, ... )

<uKeyDown> An action to perform when pressing a key.

<oParent> The container of the window.

<oBrush> Brush Object attached to the window

<oCursor> Cursor Object attached to the window

<oIcon> Icon Object attached to the window

<oMenu> Menu Object attached to the window

<nClrFore> <nClrBack> The colors to use for the windows. They may be numeric RGB colors or xBase string colors.

<uLButtonUp> The action to perform when the mouse left button is released.

<nMenuInfo> The column position where to place the automatic MDI popup menu.

<uDropFiles> The action to perform when a group of files is dropped over the window from an external application.

<nMenuInfo> The popup position in the pulldown menu of the window, where the MDI environment will automatically place information.

<cTitle> The caption of the window.

CLAUSES

MDI To be created as an MDI environment

BORDER <NONE | SINGLE> The style of the border.

NOSYSMENU | NO SYSMENU To avoid using the typicall system menu.

NOCAPTION | NO CAPTION | NO TITLE To avoid using a caption.

NOICONIZE | NOMINIMIZE To avoid the iconize button.

NOZOOM | NO ZOOM | NOMAXIMIZE | NO MAXIMIZE To avoid the maximize button.

VSCROLL | VERTICAL SCROLL To automatically show a vertical scrollbar.

ONLBUTTON To specify the action to perform when a group of files is dropped over the window from an external application.

MENUINFO To specify the popup position in the pulldown menu of the window, where the MDI environment will automatically place information.

ONDROPFILES To specify the action to perform when a group of files is dropped over the window from an external application.

HSCROLL | HORIZONTAL SCROLL To automatically show a horizontal scrollbar.

PIXEL To interpret the coordinates as pixel based instead character based

You must specify the clause MDICHILD to have all the possibilities Windows MDI offers.

MDI programming explanation

More:

What is MDI ?

Why MDI ?

How to do MDI with FiveWin

New MDI directions in FiveWin


What is MDI ?

As soon as you start getting comfortable with Windows you will face one of the more powerful features of it: Multiple Document Interface Windowing.

Most of the Windows commercial applications we use (the Windows Program Manager is written using MDI) take advantage of the possibilities of MDI.

Basically MDI environment is a main Window which has several child Windows inside which can be resized, tiled, cascaded, maximized, created and destroyed very easily. In fact, a MDI environment is like a whole Window environment all by itself.

These features, which may seem very common to you, won't work if you try to get create them using standard Windows. Well, you could do it, but it would mean a lot of code to be written.

Windows, instead, offers the MDI system to create these systems.


Why MDI ?

To make things easier! We automatically get a lot of nice and powerful features without the need to code them. Windows takes control of everything!

The elements of a MDI environment

There is just one big difference to understand about MDI programming:

Windows keeps an 'invisible' Window which extends the entire the client area of the 'frame' Window:

The real 'trick' of the MDI programming is the MDI Client Window which Windows has implemented.

Developing a MDI environment in C language is a very complicated task. In fact, it is one of the most difficult tasks for beginners. But you are lucky because doing it with CA-Clipper and FiveWin it is a very, very easy task!


How to do MDI with FiveWin

To create the main MDI frame Window we use the standard FiveWin Windows creation commands. The only difference is that you must specify the MDI clause. See above.

Now, you start creating the child Windows with the same easy commands. You don't have to worry about the 'ghost' MDI Client Window.

FiveWin automatically manages and talks to the MDI Client Window.

To create a MDI Child Window you again use the standard Window creation commands, but you must specify the clause MDICHILD.

All that you already know about FiveWin is still the same! You only have to remember a few items:

A MDI Frame Window Object has 'DATA' named oWndClient, which is another Windows Object -the 'ghost' MDI Client!-.

In fact, the surface you see inside the MDI frame is the MDI Client!!! Don't forget that. So, if -for example- you plan to place a bitmap on the surface of the MDI frame Window, you really have to place it on the MDI Client. So do this:

@ 2, 2 BITMAP ... OF oWnd:oWndClient

if you forget that, and you just do OF oWnd, you will be placing the bitmap _behind_ the MDI Client, so you will not see the bitmap!!! Remember that! That is the omly 'trick' about MDI programming.

MDI Object Oriented Implementation

If you go deeper in FiveWin architecture, you will discover there are some very powerful

Classes supporting all the Windows MDI implementation.

We have developed three main Classes which inherit from base Window Class:

· Class TMdiFrame

· Class TMdiClient

· Class TMdiChild

All of them implement new methods to encapsulate all the power Windows offers to MDI programming.

Remember this:

TMdiFrame is the main Window. It has data named oWndClient which is a TMdiClient Window.

oWndClient has a Clipper array with all the Child Windows you create. The name of that data is aWnd. It is a normal Clipper array. You may use as you wish.


New MDI directions in FiveWin

In previous releases of FiveWin, we planned to develop some new Classes inheriting from TMdiChild to suit some of the 'normal' business applications situations you will face. But now, we have found an easier approach:

Most of the MDI Child Windows you will use will be very similar to each other -once again we stress about business applications development not just 'fancy' programming-. They will have a ButtonBar attached and a main control which automatically resizes to extend the whole visible area of the Child Window.

So, we are giving you a really powerful way of developing MDI environments which is quick and clean:

The way we suggest that you manage MDI child Windows is as follows:

· First, you create the MDI frame. See above syntax.

· Next you start creating -when you need them- the child Windows: Using the above syntax:

DEFINE WINDOW [<oWnd>] ;

[ MDICHILD ] ;

[ FROM <nTop>, <nLeft> TO <nBottom>, <nRight> ] ;

[ TITLE <cTitle> ] ;

[ MENU <oMenu> ] ;

[ ICON <oIco> ] ;

[ OF <oParent> ]

· Now you create a ButtonBar for this Child Window. Use the standard syntax:

DEFINE BUTTONBAR oBar OF <oWndChild>

Attach the buttons in a normal way. Every button will have the actions you define:

DEFINE BUTTON OF oBar ACTION ...

DEFINE BUTTON OF oBar ACTION ...

...

Using this approach easily enhances the functionality of the MDI Child Window without the need to develop a new Class -you are free to do it, but only when really necessary!-

·The last step is to create a Control -whatever Class of control you need- and attach it to the Child Window:

@ 0, 0 GET <oControl>... MEMO OF <oWndChild>

@ 0, 0 LISTBOX <oControl> BROWSE ... OF <oWndChild>

etc... -any Class of Control-

And now, we tell the MDI Child to use that control as its main Control:

<oWndChild>:SetControl( <oControl> )

To start using it, you ACTIVATE the Window in the normal way:

ACTIVATE WINDOW <oWndChild> ...

And that is all!

Doing it this way you will be mastering MDI programming in a few minutes without the need to create new Classes or learning very difficult MDI programming rules.

Let CA-Clipper and FiveWin do the hard work for you. This is the power of OOPS and xBase!

See the new version of \IDE\IDE.prg for a real full example on MDI programming.


Menus

Creating a pulldown menu from source code

MENU [ <objMenu> ] [POPUP]

MENUITEM [ <oMenuItem> PROMPT ] <cPrompt> ;

[ MESSAGE <cMsg> ];

[ CHECK | CHECKED | MARK ] ;

[ ENABLED | DISABLED ] ;

[ FILE | FILENAME | DISK <cBmpFile> ];

[ RESOURCE | RESNAME | NAME <ResName> ];

[ ACTION <uAction> ] ;

[ BLOCK <bAction> ] ;

[ OF | MENU | SYSMENU <oMenu> ];

[ ACCELERATOR <nState>, <nVirtKey> ] ;

[ HELP ] ;

[ HELP ID | HELPID <nHelpId> ] ;

[ WHEN <uWhen> ];

[ BREAK ]

SEPARATOR [<oMenuItem>]

MENUITEM...

MRU <oMru> ;

[ INI | ININAME | FILENAME | NAME | DISK <cIniFile> ]

[ SECTION <cSection> ] ;

[ SIZE | ITEMS <nItems> ] ;

[ MESSAGE <cMsg> ] ;

[ ACTION <uAction> ]

ENDMENU

Creating a pulldown menu from resources

DEFINE MENU <oMenu> ;

[ RESOURCE | NAME | RESNAME <cResName> ];

[ POPUP ] ;

REDEFINE MENUITEM [ <oMenuItem> ;PROMPT <cPrompt> ] ;

[ ID <nId> OF | MENU <oMenu> ] ;

[ ACTION <uAction> ] ;

[ BLOCK <bAction> ] ;

[ MESSAGE <cMsg> ] ;

[ CHECK | CHECKED | MARK ] ;

[ ENABLED | DISABLED ] ;

[ FILE | FILENAME | DISK <cBmpFile> ];

[ RESOURCE | RESNAME | NAME <cResName> ] ;

[ ACCELERATOR <nState>, <nVirtKey> ] ;

[ HEPL ID | HELPID <nHelpId> ];

[ WHEN <uWhen> ]

DEFINE MENU <o menu> OF <oWnd>

SET MENU OF <oWnd> TO <oMenu>

Activating a Popup Menu

ACTIVATE POPUP | MENU <oMenu> ;

[ AT <nRow>, <nCol> ] ;

[ OF | WINDOW | DIALOG <oWnd> ]

Redefining the System Menu of a Window

REDEFINE SYSMENU <oMenu> ;

[ OF | WINDOW | DIALOG <oWnd> ]

-MenuItems same as above...-

ENDSYSMENU

<oMenu> A reference to the Menu Object.

<oMenuItem> A reference to one of the menuitems of the menu. Each menuitem of a menu object is also an object. SEPARATOR clause also may specify an optional menuitem variable to store its related value.

<cMsg> The associated message of this control.

<cBmpFile> The name of a BMP file to be used as the label for a menuitem of the menu.

<cResName> The resource name of the menu.

<uAction> The action to be performed for a specific menuitem.

<bAction> The same action as above expressed as a codeblock.

<nRow>, <nCol> The coordinates where to place the Popup Menu.

<oWnd> The container window of the Menu.

<nState> The state of they accelerator key (see VKEY.CH)

<nVirtKey> ASCII value of the accelerator key.

<nHelpId> The help topic identifier of a specific menuitem.

<uWhen> An expression to be bloquified and evaluated to check if a menuitem should be enabled or disabled.

<nId> The numeric resource identifier of the menuitem.

<cPrompt> The label of the menuitem.

<bAction> The action to be performed when the Button is pressed.

<oMru> A reference to a new MRU object created

<cIniFile> The name of the related INI file to use with a MRU object.

<cSection> The section inside the INI file where to store the MRU items.

<nItems> The number of items to be managed by the MRU object.

<uAction> The action to perform when selecting a MRU item.

CLAUSES

CHECK CHECKED MARK If the menuitem has to appear initially as checked.

ENABLED If the menuitem has to appear initially as enabled. by default it is enabled.

DISABLED If the menuitem has to appear initiall as disabled.

HELP If the menuitem has to appear by the op right of the pulldown menu.

POPUP To create a popup menu instead of a pulldown menu.


Meter

Creating a Meter from source code

@ <nRow>, <nCol> METER [ <oMeter> VAR ] <nActual> ;

[ TOTAL <nTotal> ] ;

[ SIZE <nWidth>, <nHeight> ];

[ OF <oWnd> ] ;

[ UPDATE ] ;

[ PIXEL ] ;

[ FONT <oFont> ] ;

[ PROMPT <cPrompt> ] ;

[ NOPERCENTAGE ] ;

[ COLOR | COLORS <nClrPane>, <nClrText> ] ;

[ BARCOLOR <nClrBar>, <nClrBText> ] ;

[ DESIGN ]

Creating a Meter from resources

REDEFINE METER [ <oMeter> VAR ] <nActual> ;

[ TOTAL <nTotal> ] ;

[ ID <nId> ] ;

[ OF <oWnd> ];

[ UPDATE ] ;

[ FONT <oFont> ] ;

[ PROMPT <cPrompt> ] ;

[ NOPERCENTAGE ] ;

[ COLOR | COLORS <nClrPane>, <nClrText> ] ;

[ BARCOLOR <nClrBar>, <nClrBText> ]

<nRow>, <nCol> The coordinates on the screen. We simulate text coordinates.

<oMeter> A reference to the Meter Object.

<nActual> The numerical variable represented by the Meter.

<nTotal> The total amount represented by the Meter.

<nWidth>, <nHeight> The dimensions of the Meter in pixels.

<oWnd> A reference to the container Window Object of the Meter.

<nId> A numerical value identifying the Meter from resources.

<oFont> The font to use to display the percentage of the meter.

<cPrompt> To display an optional text inside the meter.

<nClrPane> <nClrText> The colors of the unfilled parts of the meter

<nClrBar> <nClrBText> The colors of the filled parts of the meter.

CLAUSES

UPDATE If this control has to be updated everytime its container is updated <oDlg>:Update().

PIXEL If the coordinates of the meter are pixel based.

NOPERCENTAGE To avoid showing the '%' sign.

DESIGN Allows the user to move and resize with the mouse


MetaFile Controls

(see printing preview pages are metafiles).

@ <nRow>, <nCol> METAFILE [ <oMeta> ];

[ FILE | FILENAME | DISK <cMetafile> ];

[ OF | WINDOW | DIALOG <oWnd> ];

[ SIZE <nHeight> <nWidth> ];

[ COLOR | COLORS <nClrFore> [, <nClrBack> ] ];

REDEFINE METAFILE [ <oMeta> ];

[ ID <nId> ];

[ FILE | FILENAME | DISK <cMetafile> ];

[ OF | WINDOW | DIALOG <oWnd> ];

[ COLOR | COLORS <nClrFore> [, <nClrBack> ] ];

<nRow> <nCol> The row and col coordinates.

<oMeta> The variable to hold this object.

<cMetafile> The name of the metafile file.

<oWnd> The container of this control.

<nHeight>, <nWidth> The height and width dimensions of this control.

<nClrFore>, <nClrBack> The foreground color of the control.

The background color of the control.

<nId> The resource identifier for this control.


MRU

Most recenty used item. See Menus explanation.


MsgBar

Creating a MsgBar from source code (traditional dBase way)

SET MESSAGE [ OF <oWnd> ];

[ TO <cMsg> ];

[ CENTERED | CENTER ] ;

[ FONT <oFont> ] ;

[ CLOCK | TIME ] ;

[ DATE ] ;

[ KEYBOARD ] ;

[ COLOR | COLORS <nClrFore>;[,<nClrBack>] ] ;

[ NOINSET | NO INSET]

An alternative way (Objects creation way)

DEFINE MESSAGE [ BAR ] [ <oMsg> ];

[ OF <oWdn> ];

[ PROMPT <cMsg> ]

[ CENTERED | CENTER ] ;

[ FONT <oFont> ] ;

[ CLOCK | TIME> ] ;

[ DATE ] ;

[ KEYBOARD ] ;

[ COLOR | COLORS <nClrFore>;[,<nClrBack>] ] ;

[ NOINSET | NO INSET ]

Defining yours own MsgItems.

DEFINE MSGITEM [ <oMsgItem> ] ;

[ OF <oMsgBar> ] ;

[ PROMPT <cMsg> ] ;

[ SIZE <nSize> ] ;

[ FONT <oFont> ] ;

[ COLOR | COLORS <nClrFore>;[, <nClrBack>] ] ;

[ ACTION <uAction> ]

[ BITMAP, BITMAPS <cBitmap1> [, <cBitmap2> ] ] ;

[ TOOLTIP <cToolTip> ]

<oWnd> A reference to its container window

<cPrompt> The default msg to show

<oFont> An optional reference to a font object to use to display the msg.

<nClrFore> Foreground color as a RGB number, or as a xBase string

<nClrBack> Background color as a RGB number

<oMsgItem> A reference of the MsgItem objet.

<oMsgBar> A reference of its container MsgBar.

<nSize> Size of the MsgItem.

<uAction> The action to perform when the mouse is clicked over .

<cBitmap1>, <cBitmap2> Bitmaps to show for active and inactive state of the Msgitems

<cToolTip> Msgitem tooltip text

CLAUSES

CENTERED If the text should show centered

CLOCK | TIME Time in the MsgBar.

DATE Date in the MsgBar.

KEYBOARD Keyboard status in the MsgBar.

NOINSET For a non-inset MsgBar appearance


ODBC

Using a DataBase through ODBC

DEFINE ODBC <oDbc> ;

[ NAME <cName> ] ;

[ USER <cUser> ] ;

[ PASSWORD <cPassword> ]

Executing a SQL statement

ODBC <oDbc> [ SQL | EXECUTE ] <cCommand>

<oDbc> A variable which holds the reference to the object ODBC.

<cName> The name of the DataBase to use.

<cUser> The name of the user who is going to manage the DataBase.

<cPassword> An optional password required to use the DataBase.

<cConnect> Some ODBC drivers require a connection string, which normally includes the <cName>, <cPassword>, and other extra required information.

<cCommand> A character string which holds the ODBC statement to execute.

CLAUSES

FROM USER Means that we want to select interactively the DataBase to use.


Pages

Creating a pages control from resources

REDEFINE PAGES <oPag> ;

[ ID <nId> ] ;

[ OF <oWnd> ] ;

[ DIALOGS <DlgName,...> ] ;

[ OPTION <nOption> ]

[ ON CHANGE <uChange> ];

[ FONT <oFont> ]

<oPag> A reference to the TPages object just created.

<nId> The numeric resource identifier of the control.

<oWnd> The container object of the TPages control.

<DlgName,...> A list with the resources names of the DialogBoxes to manage. Important: These DialogBoxes must have the style STYLE WS_CHILD | WS_VISIBLE at the RC or DLL file.

<nOption> An optional initial option to use different from 1.

<uChange> An action to perform when a different page is selected on the same pages control.

<oFont> An optional font object to be used for the pages control.

CLAUSES

ON CHANGE To specify an action to perform when a different page is selected on the same pages control.

FONT To specify an optional font object to be used for the pages control.


Pen

Defining a Pen Control

DEFINE PEN <oPen> ;

[ STYLE <nStyle> ] ;

[ WIDTH <nWidth> ] ;

[ COLOR <nRGBColor> ] ;

[ OF | WINDOW | DIALOG <oWnd> ]

Activating the Pen Control

ACTIVATE PEN <oPen>

<oPen> Reference to a Pen Object.

<nStyle> An optional Pen Style.

<nRGBColor> Pen color as a RGB number, or as a xBase string.


Printer

Using the Printer

PRINT | PRINTER [ <oPrint> ] ;

[ TITLE | NAME | DOC <cDocument> ] ;

[ FROM USER ] ;

[ PREVIEW [ MODAL]];

[ TO <xModel> ]

PAGE

ENDPAGE

ENDPRINT

ENDPRINTER

<oPrint> A reference to the Printer Object.

<cDocument> The name of the document to be generated. It is the name that appears at the Spooler.

<nRow>, <Ncol> The starting coordinates of the print measured in printer resolution units. This means that different printers will generate different looking reports.

In order to avoid this (you want the same looking printout with different printers!) you need first to calculate the resolution of the printer, and then, divide those dimensions by the number of rows and columns that you want:

See SAMPLES\TestPrn2.prg

<cText> The value to print. It may be of any type. FiveWin will automatically convert it into a string expression.

<oFont> A font object to use when printing the <cText> value. See the FONT xBase commands to properly build a font. It is an optional parameter.

Important: If you want a specific dimension for that font independently from the printer used, you must specify the OF ... clause when creating the font, and after the printer object has been created:

local oPrn, oFont

PRINT oPrn

DEFINE FONT oFont NAME "Arial" SIZE 0, -8 OF oPrn

PAGE

...

ENDPAGE

ENDPRINT

oFont:End()

Important: You have to :End() the font object once you have finished and completed your printout work.

<nWidth> A specific printer units width to use when printing the <cText> value. It is an optional parameter.

<nClrText> An optional color to use when printing the <cText> value. It is an optional parameter.

CLAUSES

PAGE Starts a new page

ENDPAGE Ends the current printed page

ENDPRINT Ends printing

FROM USER Lets the user interactively select the printer to use. If you don't specify this clause, FiveWin will use the default printer installed in your system.

PREVIEW Invokes the FiveWin preview system, which lets the user interactively preview the printout before sending it to the printer.

MODAL Stop the flow of the program until the preview window is closed


PushButtons

Creating Buttons from source code

@ <nRow>, <nCol> BUTTON [ <oBtn> ]

[ PROMPT <cCaption> ] ;

[ NAME | RESNAME | RESOURCE <cResName1>;

[,<cResName2>] ] ;

[ FILE | FILENAME | DISK <cBmpFile1>;

[,<cBmpFile2>] ] ;

[ SIZE <nWidth>, <nHeight> ] ;

[ ACTION <uAction> ] ;

[ OF | WINDOW | DIALOG <oWnd> ] ;

[ MESSAGE <cMsg> ] ;

[ WHEN <WhenFunc> ] ;

[ ADJUST ] ;

[ DEFAULT ] ;

[ HELP | HELPID | HELP ID <nHelpId> ] ;

[ FONT <oFont> ] ;

[ PIXEL ] ;

[ DESIGN ] ;

[ UPDATE ] ;

[ VALID <ValidFunc> ] ;

[ CANCEL ]

Using Buttons from resources

REDEFINE BUTTON [<oBtn>] ;

[ ID <nId> ] ;

[ PROMPT <cCaption> ] ;

[ OF | BUTTONBAR <oBar> | ] ;

[ | WINDOW | DIALOG <oDlg> ] ;

[ NAME | RESNAME | RESOURCE <cResName1>;

[,<cResName2>] ] ;

[ FILE | FILENAME | DISK <cBmpFile1>;

[,<cBmpFile2>] ] ;

[ ACTION | EXEC> <uAction> ] ;

[ MESSAGE <cMsg> ] ;

[ ADJUST ] ;

[ WHEN <WhenFunc> ] ;

[ HELP | HELPID | HELP ID <nHelpId> ] ;

[ VALID <ValidFunc> ] ;

[ CANCEL ]

DEFINE BUTTON [ <oBtn> ] ;

[ OF | BUTTONBAR <oBar> ] ;

[ NAME | RESNAME | RESOURCE <cResName1>;

[,<cResName2>] ] ;

[ FILE | FILENAME | DISK <cBmpFile1>;

[,<cBmpFile2>] ] ;

[ ACTION | EXEC <uAction> ] ;

[ GROUP ] ;

[ MESSAGE <cMsg> ] ;

[ ADJUST ] ;

[ WHEN <WhenFunc> ]

<nRow>, <nCol> The coordinates of the Button. They mimic text mode coordinates.

<oBtn> A reference to the Button Object.

<oBar> A reference to the Button

<cCaption> The label of the Button.

<cBpFile1> <cBmpFile2> The file name of the bitmap as a Picture Button.When a second

bitmap is provided it is displayed as the Button in a depressed state.

<nHelpId> The help topic identifier of the Button.

<oWnd> The container window of the Button.

<uAction> The action to be performed when the Button is pressed.

<oFont> A reference to the Font Object to use with the Button.

<nWidth> <nHeigth> The dimensions of the Button.

<cResName1> <cResName2> The bitmap resource to display as a Picture Button. When a

second bitmap resource is provided it is displayed as the Button in a depressed state.

<cMsg> The associated message of this control

<WhenFunc> It is an expression to evaluate indicating if the control is or not enable.

<nId> The numeric resource identifier of the Control.

<ValidFunc> An expression to validate when the control is going to lose the focus.

CLAUSES

DEFAULT For default PushButtons: Automatically executes when the user press Enter, even from other controls.

Use this clause only when building the Button from source code. When using resources, this clause must be specifies from the resource editor.

DESIGN Allows the user to move and resize with the mouse

PIXEL To use pixel coordinates instead of Text coordinates.

UPDATE This control may be updated from TDialog:Update() METHOD

CANCEL To avoid any pending VALID.


RadioButtons

Creating a RadioButton Menu from source code

@ <nRow>, <nCol> RADIO [ <oRadMenu> VAR ] <nVar> ;

PROMPT | ITEMS <cItems,...> ] ;

[ OF | WINDOW | DIALOG <oWnd> ] ;

[ HELPID | HELP ID <nHelpId,...> ] ;

[ ON CLICK | ON CHANGE <uChange> ]

[ COLOR | COLORS <nClrFore>;[,<nClrBack>] ] ;

[ MESSAGE <cMsg> ] ;

[ UPDATE ] ;

[ WHEN <uWhen> ] ;

[ SIZE <nWidth>, <nHeight> ] ;

[ VALID <uValid> ] ;

[ DESIGN ] ;

[ 3D ] ;

[ PIXEL ]

Creating a RadioButton Menu from resources

REDEFINE RADIO [ <oRadMenu> VAR ] <nVar> ;

[ ID <nId,...> ] ;

[ OF | WINDOW | DIALOG <oWnd> ] ;

[ HELPID | HELP ID <nHelpId,...> ] ;

[ ON CLICK | ON CHANGE <uChange> ]

[ COLOR | COLORS <nClrFore>;[,<nClrBack>] ] ;

[ MESSAGE <cMsg> ] ;

[ UPDATE ] ;

[ WHEN <uWhen> ] ;

[ VALID <uValid> ]

<nRow>, <nCol> The coordinates of the RadioButton Menu. We simulate text coordinates.

<oRadMenu> A reference to the RadMenu Object.

<nVar> The numeric variable which controls the RadioButton Menu.

<cItems> A list of strings defining the prompts to be used as radio elements.

<oWnd> A reference to the container Window of the Radio Button Menu.

<nHelpId> A list of numeric help identifier to associate to each radio control.

<uChange> An action to be performed when a new radio is selected at the RadioButton Menu.

<cMsg> The associated message of this control

<WhenFunc> It is an expression to evaluate indicating if the control is or not enable.

<nWidth> <nHeigth> The dimensions of the control.

<uValid> An expression to validate when the control is going to lose the focus.

CLAUSES

3D 3D look.

UPDATE This control may be updated from TDialog:Update() METHOD

DESIGN Allows the user to move and resize with the mouse.

PIXEL To use pixel coordinates instead of Text coordinates.


Reports

General syntax:

REPORT ...

COLUMN ...

COLUMN ...

[ GROUP ... ]

ENDREPORT

ACTIVATE REPORT ...

Report creation:

REPORT [ <oReport> ] ;

[ TITLE <bTitle, ...> [< LEFT | CENTER | CENTERED | RIGHT > ] ];

[ HEADER <bHead, ...> [< LEFT | CENTER | CENTERED | RIGHT > ] ];

[ FOOTER <bFoot, ...> [< LEFT | CENTER | CENTERED | RIGHT > ] ];

[ FONT <oFont, ...> ] ;

[ PEN <oPen, ...> ] ;

[ SUMMARY ] ;

[ FILE | FILENAME | DISK <cRptFile> ] ;

[ NAME | RESNAME | RESOURCE <cResName> ] ;

[ TO PRINTER ] ;

[ PREVIEW ] ;

[ TO FILE <toFile> ] ;

[ TO DEVICE <oDevice> ] ;

[ CAPTION <cName> ]

<oReport> Variable that holds the report object

<bTitle, ...> List of line titles separated by commas. You can use any expression that returns a string

<bHead, ...> List of line headers separated by commas. You can use any expression that returns a string

<bFoot, ...> List of line footers separated by commas. You can use any expression that returns a string

<oFont, ...> List of Fonts object separated by commas. See the programming guide for more explanation on how to change the default font of every section of the report

<oPen, ...> List of pens separated by commas

<cRptFile> Name of the configuration text file to use (Not implemented yet)

<cResName> Name of the configuration resource file to use (Not implemented yet)

<toFile> Name of the Ascii file to use for the output report

<oDevice> The target device where to print

<cName> Name of the report for the Windows printer manager

CLAUSES

SUMMARY Not detailed report body information, only report groups.

TO PRINTER Print directly to the default printer device. This clause is incompatible with the TO DEVICE clause

PREVIEW Shows a preview on screen of the report. This clause is incompatible with the TO DEVICE clause

Group creation:

GROUP [ <oRptGrp> ] ;

[ ON <bGroup> ] ;

[ HEADER <bHead> ] ;

[ FOOTER <bFoot> ] ;

[ FONT <uFont> ] ;

[ EJECT ]

<oRtpGrp> Variable that holds the group object

<bGroup> Expression to use for controlling the group breaks

<bHeader> Expression to use for the group header. It should return a String

<bFooter> Expression to use for the group footer. It should return a String

<uFont> Ordinal font to use in the list of fonts of the report object. It can be an expression that return a numeric value in the range from 1 to the quantity of the fonts defined on the report object

CLAUSES

EJECT Performs a page eject after every group break

Column creation:

COLUMN [ <oRptCol> ] ;

[ TITLE <bTitle, ...> ] ;

[ AT <nCol> ] ;

[ DATA <bData, ...> ] ;

[ SIZE <nSize> ] ;

[ PICTURE <cPicture, ...> ] ;

[ FONT <uFont> ] ;

[ TOTAL [ FOR <bTotalExpr> ] ] ;

[ LEFT | CENTER | CENTERED | RIGHT ] ;

[ SHADOW ] ;

[ GRID [ <nPen> ] ]

<oRptCol> Variable that holds the column object

<bTitle, …> List of column title lines separated by commas. You can use any expression that returns a string

<nCol> Exact column to use in pixels. Not used normally since the report engine automatically centers the report on the page and makes all the calculations for you

<bData, …> List of column data lines separated by commas. You can use any expression.

<nSize> Size of the column in characters. By default the report engine uses the for the calculations since the font used may be proportional

<cPicture, …> List of pictures to use for every data line separated by commas

<uFont> Ordinal font to use in the list of fonts of the report object. It can be an expression that return a numeric value in the range from 1 to the quantity of the fonts defined on the report object

<bTotalExpr> When this expression returns TRUE all the numeric data of the column will be added for the TOTAL info. If the expression return FALSE then the TOTAL value will not be affected for the current record. This clause is useful when creating master-detail reports

<nPen> Ordinal pen to use in the list of pens of the report object. It can be an expression that return a numeric value in the range from 1 to the quantity of the pens defined on the report object.

CLAUSES

TOTAL Creates a total on that column. If any group are defined it will also create a sub-total on every group brake

LEFT | CENTER | CENTERED | RIGHT Alignment of the column

SHADOW Creates a ligh gray shadow on that column

Finishing report definition:

ENDREPORT

Report activation:

ACTIVATE REPORT <oReport> ;

[ FOR <bfor> ] ;

[ WHILE <bwhile> ] ;

[ ON INIT <bInit> ] ;

[ ON END <bEnd> ] ;

[ ON POSTEND <bPostEnd> ];

[ ON STARTPAGE <bStartPage> ] ;

[ ON ENDPAGE <bEndPage> ] ;

[ ON POSTPAGE <bPostPage> ];

[ ON STARTGROUP <bStartGroup> ] ;

[ ON ENDGROUP <bEndGroup> ] ;

[ ON POSTGROUP <bPostGroup> ];

[ ON STARTLINE <bStartLine> ] ;

[ ON ENDLINE <bEndLine> ] ;

[ ON CHANGE <bChange> ]

<oReport> Variable that holds the report object

<bFor> A expression which holds the FOR clause.

<bWhile> A expression which holds the WHILE clause. By default: .not. EOF() }

<bInit> A expression to evaluate at the beginning of the report

<bEnd> A expression to evaluate at the end of the report but before the grand totals are printed

<bPostEnd> A expression to evaluate at the end of the report

<bStartLine> A expression to evaluate at the beginning of every report body line

<bEndLine> A expression to evaluate at the end of every report body line

<bStartPage> A expression to evaluate a the beginning of every report page

<bEndPage> A expression to evaluate a the end of every report page but before the page totals are printed

<bPostPage> A expression to evaluate a the end of every report page

<bStartGroup> A expression to evaluate a the beginning of every group break

<bEndGroup> A expression to evaluate a the end of every group break but before group totals are printed

<bPostGroup> A expression to evaluate a the end of every group break

<bChange> A expression to evaluate on every record or list process. The expression is evaluated after the record is processed.


Resources

You may store your application's resources in a DLL, or embed them inside your EXE file use the Microsoft RC.EXE resource compiler.

To use resources from inside a DLL:

Using DLLs as resources:

SET RESOURCES TO <cDllName> [,<cDllName>... ]

Selecting one of the opened resources

SET RESOURCES TO <cDllName>

Ending the use of the resource

SET RESOURCES TO <cDllName> Is the name of a DLL where resources have been placed. It is possible to specify multiple DLLs for resources.

After opening several DLLs as resources it is necessary to select the one we are going to use. To do so we must again issue the command:

SET RESOURCES TO <TheSameResourceName>

It is similar to selecting a certain Work Area.

To use resources from inside your EXE:

No special command is required. Just call:

RC.EXE -K MyApp.rc MyApp.exe

After linking your EXE, provide an RC file with all the resource definitions for your application. The SAMPLES\Build.bat we provide automatically calls RC.EXE if a RC is defined with the same name as the .prg you are building with build.bat. Applications requiring multiple .prgs, must have their own .rmk file or batch file to build them. Use the above mentioned RC.EXE syntax to embed your resources into your final .exe

RC.EXE is the Windows resource compiler and it is a utility you may get from any Windows C/C++ compiler. FiveWin does not provide RC.EXE.

Setting a variable contents from a resource string:

REDEFINE <uVar>

[ AS [ CHARACTER| NUMERIC | LOGICAL | DATE ] ];

[ RESOURCE | RESNAME | NAME <nIdRes> ];

<uVar> The string resource identifier.

<nIdRes> The name of the Clipper variable.

CLAUSES


Say

Defining a SAY object from source code

@ <nRow>, <nCol> SAY [ <oSay> PROMPT | VAR ] <cText> ;

[ OF | WINDOW | DIALOG <oWnd> ] ;

[ PICTURE <cPicture> ] ;

[ COLOR | COLORS <nClrFore>;[,<nClrBack>] ] ;

[ FONT <oFont> ] ;

[ CENTERED | CENTER ] ;

[ RIGHT ] ;

[ BORDER ] ;

[ PIXEL | PIXELS ]

[ SIZE <nWidth>, <nHeight> ] ;

[ DESIGN ] ;

[ UPDATE ] ;

[ SHADED | SHADOW ] ;

[ BOX ] ;

[ RAISED ]

Redefining a SAY object from resources

REDEFINE SAY <oSay> ;

[ PROMPT | VAR <cText> ] ;

[ ID <nId> ];

[ OF | WINDOW | DIALOG <oDlg> ] ;

[ COLOR | COLORS <nClrFore>;[,<nClrBack>] ] ;

[ PICTURE <cPict> ] ;

[ UPDATE ] ;

[ FONT <oFont> ]

<nRow>, <nCol> The coordinates of the Say Object. We simulate Text coordinates.

<oSay> A reference to the Say Object.

<cText> The label of the Say Object.

<oWnd> The container dialog of the Say control.

<cPicture> The typical PICTURE clause for a SAY.

<cColor> The COLOR string for the SAY. Not available yet!

<oFont> The Object font to be used with the SAY. The Font must be created previously using DEFINE FONT... .

<nClrFore> Foreground color as a RGB number, or as a xBase string

<nClrBack> Background color as a RGB number

<nWidth>, <nHeigth> The dimensions of the control.

<oSay> A reference to the Say Object.

<cText> The caption to assign to the Say Object. Specifying it change the text on the resource.

<nId> The numeric resource identifier of the Say Object. Is has to be assigned from the resource editor.

<oWnd> The container dialog of the Say Object.

CLAUSES

CENTERED CENTER Center text.

RIGHT Right justification.

BORDER Create a border arround the control.

DESIGN Allows the user to move and resize with the mouse

PIXEL To use pixel coordinates instead of Text coordinates.

UPDATE This control may be updated from TDialog:Update() METHOD

SHADED, SHADOW To paint the say with a shaded effect.

BOX Place the say objet in a box.

RAISED To paint the say with a raised effect.

AS To specify the type of the variable value we want to get.


Selector

Defining a SELECTOR object from source code:

@ <nRow>, <nCol> SELECTOR [ <oSelec> VAR ] <nVar> ;

[ ORIGIN ANGLE <nAngle1> ] ;

[ LAST ANGLE <nAngle2> ] ;

[ RANGE <nMin>, <nMax> ] ;

[ MARKS <nMarks> ] ;

[ EXACT ] ;

[ OF | WINDOW | DIALOG <oDlg> ] ;

[ COLOR | COLORS <nClrFore>;[,<nClrBack>] ] ;

[ MESSAGE <cMsg> ] ;

[ DESIGN ] ;

[ PIXEL ] ;

[ SIZE <nWidth>, <nHeight> ] ;

[ UPDATE ] ;

[ ON CHANGE <uChange> ] ;

[ ON THUMBPOS <uPos> ]

Redefining a SELECTOR object from resources:

REDEFINE SELECTOR [ <oSelec> VAR ] <nVar> ;

[ ID <nId> ] ;

[ ORIGIN ANGLE <nAngle1> ] ;

[ LAST ANGLE <nAngle2> ] ;

[ RANGE <nMin>, <nMax> ] ;

[ MARKS <nMarks> ] ;

[ EXACT ] ;

[ OF | WINDOW | DIALOG <oDlg> ] ;

[ COLOR | COLORS <nClrFore>;[,<nClrBack>] ] ;

[ MESSAGE <cMsg> ] ;

[ UPDATE ] ;

[ ON CHANGE <uChange> ] ;

[ ON THUMBPOS <uPos> ]

<nRow>, <nCol> The coordinates of the Selector Object. We simulate Text coordinates.

<oSelec> A reference to the Selector Object.

<nAngle1> Origin angle of first selector mark in sexagesimals degree

<nAngle2> Origin angle of last selector mark in sexagesimals degree

<nMin>, <nMax> Selector range values

<nMarks> Number of selector marks

<nClrFore>, <nClrBack> Selector foreground and background colors

<oWnd> The container dialog of the Slider control.

<cMsg> The associated message of this control

<nWidth>, <nHeigth> The dimensions of the control.

<nId> The numeric resource identifier of the Slider Object. Is has to be assigned from the resource editor.

<uChange> An action to be performed when the selector changes

<uPos> An action to be performed when the selector is moved by the user and left on a different position. The new position is automatically provided as nPos value.

CLAUSES

EXACT When moving the selector it readjust itself to the the nearest mark strip.

DESIGN Allows the user to move and resize with the mouse

PIXEL To use pixel coordinates instead of Text coordinates.

UPDATE This control may be updated from TDialog:Update() METHOD

Samples: fw\samples\testsele.prg


Serial Communications

Communications commands

DEFINE COMM <oComm>

[ STOP <nStop> ];

[ BAUD <nBaud> ];

[ PARITY <cParity> ];

[ INSIZE <nInQueue> ];

[ OUTSIZE <nOutQueue> ];

[ DEVICE <nDevice> ];

[ DATA <nData> ];

DEFINE LPT <oComm>

[ STOP <nStop> ];

[ BAUD <nBaud> ];

[ PARITY <cParity> ];

[ INSIZE <nInQueue> ];

[ OUTSIZE <nOutQueue> ];

[ DEVICE <nDevice> ];

[ DATA <nData> ];

WRITE COMM <oComm> STRING <cString>

CLOSE COMM <oComm>

SETUP COMM <oComm>

BREAK COMM <oComm>

UNBREAK COMM <oComm>

FLUSH COMM <oComm> NUMBER <nNumber>

ESCAPE COMM <oComm> NUMBER <nCode>

<oComm> The variable to hold this object.

<nNumber> Number of queue to flush.

<nData> Number of bits.

<nCode> Escape code to send.

<cString> A text to send.

<nDevice> Device number.

<nBaud> Bauds speed.

<nOutQueue> Size of the out queue in bytes.

<cParity> Parity "y" yes or "n" no.

<nStop> Number of stop bytes.


Set Multiple

Running multiple instances of a FiveWin EXE (only woks under Win 3.1)

SET MULTIPLE [ ON | OFF ]


ScrollBars

Creating a ScrollBar from source code

@ <nRow>, <nCol> SCROLLBAR [<oSbr>] ;

[ HORIZONTAL | VERTICAL ] ;

[ RANGE <nMin>, <nMax> ] ;

[ PAGESTEP <nPgStep> ] ;

[ SIZE <nWidth>, <nHeight> ] ;

[ UP | ON UP <uUpAction> ] ;

[ DOWN | ON DOWN <uDownAction> ] ;

[ PAGEUP | ON PAGEUP <uPgUpAction> ] ;

[ PAGEDOWN | ON PAGEDOWN <uPgDownAction> ] ;

[ ON THUMBPOS <uPos> ] ;

[ PIXEL ] ;

[ COLOR | COLORS <nClrFore>;[,<nClrBack>] ] ;

[ MESSAGE <cMsg> ] ;

[ UPDATE ] ;

[ WHEN <uWhen> ] ;

[ VALID <uValid> ] ;

[ DESIGN ] ;

[ OF <oWnd> ]

Creating a ScrollBar from resources

REDEFINE SCROLLBAR [ <oSbr> ] ;

[ ID <nID> ] ;

[ RANGE <nMin>, <nMax> ] ;

[ PAGESTEP <nPgStep> ] ;

[ UP | ON UP | ON LEFT <uUpAction> ] ;

[ DOWN | ON DOWN | ON RIGHT <uDownAction> ] ;

[ PAGEUP | ON PAGEUP <uPgUpAction> ] ;

[ PAGEDOWN | ON PAGEDOWN <uPgDownAction> ] ;

[ ON THUMBPOS <uPos> ] ;

[ COLOR | COLORS <nClrFore>;[,<nClrBack>] ] ;

[ OF <oDlg> ]

[ MESSAGE <cMsg> ] ;

[ UPDATE ] ;

[ WHEN <uWhen> ] ;

[ VALID <uValid> ]

For 'non-true ScrollBars' (when using WS_VSCROLL or WS_HSCROLL styles )

DEFINE SCROLLBAR [ <oSbr> ] ;

[ HORIZONTAL | VERTICAL ] ;

[ RANGE <nMin>, <nMax> ] ;

[ PAGESTEP <nPgStep> ] ;

[ UP | ON UP <uUpAction> ] ;

[ DOWN | ON DOWN <uDownAction> ] ;

[ PAGEUP | ON PAGEUP <uPgUpAction> ] ;

[ PAGEDOWN | ON PAGEDOWN <uPgDownAction> ] ;

[ ON THUMBPOS <uPos> ] ;

[ COLOR | COLORS <nClrFore>;[,<nClrBack>] ] ;

[ OF | WINDOW | DIALOG <oWnd> ];

[ MESSAGE <cMsg> ] ;

[ UPDATE ];

[ WHEN <uWhen> ] ;

[ VALID <uValid> ]

<nRow>, <nCol> The coordinates of the ScrollBar. We simulate Text coordinates.

<oSbr> A reference to the ScrollBar Object.

<oDlg> The container window of the ScrollBar.

<nMin>, <nMax> The range of values to be represented by the scrollbar.

<nPgStep> The increment of value when PageUp or PageDown is selected on the Scrollbar. That is, when clicking between the thumb and the top arrow or when clicking between the thumb and the bottom arrow.

<nWidth> <nHeight> The dimensions in pixels of the ScrollBar.

<uUpAction> An action to be performed when going up is selected on the scrollbar. That is, when clicking on the top arrow or when pressing the key K_UP.

<uDownAction> An action to be performed when going down is selected on the scrollbar. That is, when clicking on the bottom arrow or when pressing the key K_DOWN.

<uPgUpAction> An action to be performed when page up is selected on the scrollbar. That is, when clicking between the thumb and the top arrow.

<uPgDownAction> An action to be performed when page down is selected on the Scrollbar. That is, when clicking between the thumb and the bottom arrow.

<uPos> An action to be performed when the thumb is moved by the user and left on a different position. The new position is automatically provided as nPos value.

<nId> The numeric resource identifier of the Control.

<nClrFore> Foreground color as a RGB number, or as a xBase string

<nClrBack> Background color as a RGB number

<uValid> An expression to validate when the control is going to lose the focus.

<cMsg> The associated message of this control

<uWhen> It is an expression to evaluate indicating if the control is or not enable.

CLAUSES

HORIZONTAL VERTICAL To use a horizontal or vertical scrollbar. Only useful when creating from source code.

PIXEL To use pixel coordinates instead of Text coordinates.

DESIGN Allows the user to move and resize with the mouse

UPDATE This control may be updated from TDialog:Update() METHOD


Splitter controls

REDEFINE SPLITTER [ <oSplit> ];

[ ID <nId> ];

[ HORIZONTAL];

[ VERTICAL];

[ PREVIOUS CONTROLS <aPrevControls,....> [ NO ADJUST ] ];

[ HINDS CONTROLS <aHindControls,...> [ NO ADJUST ] ];

[ TO MARGIN | LEFT MARGIN <nMargin 1> ];

[ BOTTOM MARGIN | RIGHT MARGIN <nMargin2> ];

[ OF | WINDOW | DIALOG <oWnd> ];

[ ON CHANGE <uChange,...>];

[ 3D | 3DLOOK | _3D | _3DLOOK ];

[ COLOR | COLORS <nClrBack> ];

[ UPDATE ]

@ <nRow>,<nCol> SPLITTER [ <oSplit> ];

[ HORIZONTAL ];

[ VERTICAL ];

[ PREVIOUS CONTROLS <aPrevControls,....> [ NO ADJUST ] ];

[ HINDS CONTROLS <aHindControls,...> [ NO ADJUST ] ];

[ TO MARGIN | LEFT MARGIN <nMargin 1> ];

[ BOTTOM MARGIN | RIGHT MARGIN <nMargin2> ];

[ SIZE <nWidth>, <nHeight> ];

[ PIXEL ];

[ OF | WINDOW | DIALOG <oWnd> ];

[ ON CHANGE <uChange,...> ];

[ 3D | 3DLOOK | _3D | _3DLOOK ];

[ COLOR | COLORS <nClrBack> ];

[ DESIGN ];

[ UPDATE ]

<oSplit> The variable to hold this object.

<nRow>, <nCol> The row and col coordinates.

<nMargin2>, <nMargin1> To optionally specify the splitter area margins.

<aPrevControls,....> An array with the previous splitter controls to be resized.

<nClrBack> The background color of the splitter.

<aHindControls,...> An array with the next splitter controls to be resized.

<nId> The resource identifier for this control.

<uChange,...> CodeBlock to perform when moving from row to row

<oWnd> The conatiner of this control.

<nWidth>, <nHeight> The width and height dimensions of the control.

CLAUSES

PIXEL To specify pixel dimensions.

UPDATE To repaint this control when its container gets :Updated()

DESIGN To drag around this control using the mouse.


Struct

C like structures (#include Struc.ch)

STRUCT <oStruct>

MEMBER <cName> AS <type>

[ LEN <nLen> ];

[ INIT <uValue> ];

ENDSTRUCT

<oStruct> The variable to hold this object.

<type> The struct member type.

<nLen> The struct member length.

<cName> The struct member name.

<uValue> The struct member initial value.

Fivewin Structures (#include Exstruc.ch)

STRUC <oStruct>

MEMBER <xData, ...> ;

[ AS LOGICAL, NUMERIC, NUMBER, CHARACTER, DATE, BLOCK, ARRAY, OBJECT ] ;

[ DEFAULT, INIT <default> ] ;

[ SIZE <nSize> ]

MEMBER <oSt> AS STRUC

END STRUC

<oStruct> The variable to hold this object.

<xData>, ... The struct member names separated by commas (only the first 9 characters are relevant)

<default> Default value for the structure member/s

<nSize> The struct member size

<oSt> The struct member as another strucure

CLAUSES

AS LOGICAL, NUMERIC, NUMBER, CHARACTER, DATE, BLOCK, ARRAY, OBJECT, STRUC The structure member type

Note: The two type of structures can not be used in the same PRG file since they use the same syntax.


TcBrowse

@ <nRow>, <nCol> [ COLUMN ] BROWSE <oBrw>

[ [ FIELDS] <Flds,...> ];

[ ALIAS <cAlias> ];

[ FIELDSIZES | SIZES | COLSIZES <aColSizes, ...> ];

[ HEAD | HEADER | HEADERS <aHeaders, ....> ];

[ SIZE <nHeigth> <nWidth> ];

[ DIALOG <oDlg> ];

[ SELECT <cField> FOR <uValue1> [ TO <uValue2> ] ];

[ ON CHANGE | ON CLICK <uChange> ];

[ ON [ LEFT ] DBLCLICK <uLDblClick> ];

[ ON RIGHT CLICK <uRClick> ];

[ FONT <oFont> ];

[ CURSOR <oCursor> ];

[ COLOR | COLORS <uClrFlore> [ <nClrBack> ];

[ MESSAGE <cMsg> ];

[ UPDATE ];

[ PIXEL ];

[ WHEN <uWhen> ];

[ DESIGN ];

[ VALID <uValid> ];

DEFINE COLUMN <oCol>

[ DATA | SHOWBLOCK <uData> ];

[ TITLE | HEADER <cHead> [ OEM | ANSI | CONVERT ] ];

[ COLORS | COLOURS <uClrFlore> [ <nClrBack> ];

[ ALIGN ] [ LEFT | CENTERED | RIGHT ];

[ WIDTH | SIZE <nWidth> [ PIXELS ] ];

[ PICTURE <cPicture> ];

[ BITMAP ];

[ EDITABLE ];

[ MESSAGE <cMsg> ];

[ VALID <uValid> ];

[ ERROR [MSG] [MESSAGE ] <cErr> ];

[ NOBAR | NOHILITE ];

[ ORDER | INDEX | TAG <cOrder> ];

REDEFINE [ COLUMN ] BROWSE <oBrw>

[ <Flds,...> ];

[ ID <nId> ];

[ OF | DIALOG <oDlg> ];

[ FIELDSIZES | SIZES | COLSIZES <aColsizes,...> ];

[ HEAD | HEADER | HEADERS <aHeaders, ....> ];

[ SELECT <cField> FOR <uValue1> [ TO <uValue2> ] ];

[ ON CHANGE | ON CLICK <uChange> ];

[ ON [ LEFT ] DBLCLICK <uLDblClick> ];

[ ON RIGHT CLICK <uRClick> ];

[ FONT <oFont> ];

[ CURSOR <oCursor> ];

[ COLOR | COLORS <uClrFlore> [ <nClrBack> ];

[ MESSAGE <cMsg> ];

[ UPDATE ];

[ WHEN <uWhen> ];

[ VALID <uValid> ];

ADD [ COLUMN ] TO [ BROWSE ] <oBrw>

[ ODBF | FIELD <field> ];

[ DATA | SHOWBLOCK <uData> ];

[ COLORS | COLOURS <uClrFore> [ <uClrBack> ];

[ ALIGN ] [ LEFT | CENTERED | RIGHT ];

[ WIDTH | SIZE <nWidth> [ PIXELS ] ];

[ PICTURE <cPicture> ];

[ BITMAP ];

[ EDITABLE ];

[ MESSAGE <cMsg> ];

[ VALID <uValid> ];

[ ERROR [MSG] [MESSAGE ] <cErr> ];

[ NOBAR | NOHILITE ];

[ ORDER | INDEX | TAG <cOrder> ];

[ ELM | ELEMENT <elm> ];

[ TITLE | HEADER <cHead> ];

[ OEM | ANSI | CONVERT ];

[ PICTURE <cPicture> ];

<Flds,...> The list of fields or expressions to display on the browse.

<cAlias> The workarea alias where the browse was created.

<aHeaders, ....> Array of texts for the Header of each column.

<aColSizes, ...> Array of sizes for each column.

<oDlg> The window or dialog container of this control.

<uLDblClick> An optional action to perform when doble clicking on the browse.

<uValue1><uValue2> FOR clause expression in SELECT ... FOR ... TO ...

<oFont> An optinal font object to use.

<nHeigth> <nWidth> The height and width dimensions.

<nId> The resource identifier for this control.

<cField> The name of the field to use for a column object.

<uClrFore> <uClrBack> The fore and background colors to use.

<uChange> An optional action to perform everytime a row is selected.

<uRClick> An optional action to peform when the mouse is right clicked.

<oCursor> An optional cursor object to use.

<uWhen> A WHEN clause to evaluate

<cMsg> A related msg text to display on its container message bar.

<uData> A codeblock to evaluate to get the column containts.

<uValid> A VALID clause to evaluate.

<cOrder> The name of the index order to activate.

<cHead> The column header text.

<cPicture> An optional picture clause to use for the column containts.

<cErr> An optional error message to show when editing the column containts.

<elm> To include this column on a certain column position.

CLAUSES

PIXEL To specify pixel coordinates.

UPDATE To update this control when its container is updated.

OEM, ANSI, CONVERT To automatically convert the column data from Oem To Ansi and viceversa.

LEFT, CENTERED, RIGHT To set the column data alignment.

EDITABLE To enable the automatic editing of the column cell.


Tabs

Creating a tab from source code

@ <nRow>, <nCol> TABS [<oTabs>] ;

[ OF | WINDOW | DIALOG <oWnd> ] ;

[ PROMPT | PROMPTS | ITEMS <cPrompt,...> ] ;

[ ACTION | EXECUTE | ON CHANGE <uAction> ] ;

[ PIXEL ] ;

[ DESIGN ] ;

[ COLOR | COLORS <nClrFore> [,<nClrBack>] ] ;

[ OPTION <nOption> ] ;

[ SIZE <nWidth>, <nHeight> ] ;

[ MESSAGE <cMsg> ]

Creating a tab from resources

REDEFINE TABS [<oTabs>] ;

[ ID <nId> ] ;

[ OF | WINDOW | DIALOG <oWnd> ] ;

[ PROMPT | PROMPTS | ITEMS <cPrompt,...> ] ;

[ ACTION | EXECUTE <uAction> ] ;

[ COLOR | COLORS <nClrFore> [,<nClrBack>] ] ;

[ OPTION <nOption> ]

<nRow>, <nCol> The coordinates where to locate the tab control (only from source code, not from resources).

<oTabs> A reference to the tab object just created.

<oWnd> The container object of the tab control.

<cPrompt> A list of strings, one for each tab.

<uAction> The action to execute when selecting any tab.

<nClrFore> The color to display the prompts text.

<nClrBack> The color to fill the folder surface.

<nOption> An optional initial option to use different from 1.

<nWidth>, <nHeight> The dimensions of the tab control.

<cMsg> An optional message to display on its container MsgBar if defined.

<nId> The numeric resource identifier of the control.

CLAUSES

PIXEL To use pixel coordinates instead of text coordinates.

DESIGN Allows the user to interactively move and resize the control.

ON CHANGE To specify an action to execute when a different tab option is selected.


Timers

Defining a new Timer

DEFINE TIMER <oTimer> ;

[ INTERVAL <nInterval> ] ;

[ ACTION <uAction> ] ;

[ OF | WINDOW | DIALOG <oWnd> ]

ACTIVATE TIMER <oTimer>

DEACTIVATE TIMER <oTimer>

RELEASE TIMER <oTimer>

<oTimer> A reference to the Timer Object.

<nInterval> Defines the timer interval in thousandths of seconds.

<uAction> The action to be performed when the interval period is reached.

<oWnd>


Trees

Creating a tree

TREE [ <oTree> ] ;

[ BITMAPS <cBmpOpen>, <cBmpClose> ]

TREEITEM [<oItem> PROMPT ] <cLabel> ;

[ RESOURCE <cResName1> [, <cResName2> ] ] ;

[ FILENAME <cBmpOpen> [, <cBmpClose> ] ] ;

[ OPENED | OPEN ] ...

[ TREE <oSubTree> ]

[ TREEITEM ... ]

[ ... ]

[ ENDTREE ]

ENDTREE

<oTree> A reference to the TTree object just created.

<cBmpOpen> <cBmpClosed> Optional bitmaps files or resources names for the tree nodes

open and close states images.

<oItem> A reference to the TTreeItem object just created.

<cLabel> The prompt of an TreeItem element.

<cResName1> <cResName2>Optional bitmaps resources names for the item open and

closed states images. The Tree <cBmpOpen> and <cBmpClosed> are used by default if <cResName1> and <cResName2> are not specified.

<cBmpOpen> Optional bitmaps file names for the item open and closed

<cBmpClosed> states images. The Tree <cBmpOpen> and <cBmpClosed> are used by default if <cResName1> and <cResName2> are not specified.

<oSubTree> A reference to the TTree object just created.

A reference to the container Window Object.


Video

Defining a video Control from source code

@ <nRow>, <nCol> VIDEO <oVideo> ;

[ SIZE <nWidth>, <nHeigth> ] ;

[ FILE | FILENAME | DISK <cAviFile> ] ;

[ OF | WINDOW | DIALOG <oWnd> ]

[ NO BORDER ];

Redefining a Video Control from resources

DEFINE VIDEO <oVideo> ;

[ ID <nId> ] ;

[ FILE | FILENAME | DISK <cAviFile> ] ;

[ OF | WINDOW | DIALOG <oWnd> ]

REDEFINE VIDEO [ <oVideo> ];

[ ID <nId> ];

[ OF | WINDOW | DIALOG <oWnd> ];

[ WHEN <uWhen> ];

[ VALID <uValid> ];

[ FILE | FILENAME | DISK <cFilename> ];

Activating the Video

ACTIVATE VIDEO <oVideo>

<cFileName> The name of the AVI file to play.

<nRow>, <nCol> The control coordinates. We simulate Text coordinates.

<oVideo> A reference to the Video Object.

<nWidth>, <nHeight> The Control dimensions.

<cAviFile> The name of the AVI file to be played.

<oWnd> A reference to the container Window of the Control.

<WhenFunc> It is an expression to evaluate indicating if the control is or not enable.

<ValidFunc> An expression to validate when the control is going to lose the focus.

CLAUSES

NOBORDER To avoid painting the control border.


VBXs

Creating a VBX from source code (using a VBX on a window)

@ <nRow>, <nCol> VBX [<oVbx>] ;

[ OF <oWnd> ] ;

[ SIZE <nWidth>, <nHeight> ] ;

[ FILE | FILENAME | DISK <cVbxFile> ] ;

[ CLASS <cVbxClass> ] ;

[ ON <cClause1> <uAction1> ;

[ ON <cClauseN> <uActionN> ] ]

[ WHEN <uWhen> ] ;

[ VALID <uValid> ] ;

[ PIXEL ] ;

[ DESIGN ]

Warning: Some VBXs controls need some specific initialization data, and may not work properly using them on windows. In those cases, use them only in DialogBoxes using REDEFINE VBX ...

Creating a VBX from resources (using a VBX on a dialog box)

REDEFINE VBX [<oControl>] ;

[ ID <nId> ] ;

[ OF <oDlg> ] ;

COLOR <nClrFore> [,<nClrBack>] ] ;

[ ON <cClause1> <uAction1> ;

[ ON <cClauseN> <uActionN> ] ]

<nRow>, <nCol> The screen coordinates

<oVbx> A reference to the oVbx control object

<nWidth>, <nHeight> The dimensions of the oVbx control

<cVbxFile> The filename of the .VBX file

<cVbxClass> Optional VBX class name specified by the manufacturer

<cClause> Any event name specified by the VBX manufacturer

<uAction> Any action to execute on that event

<nId> The oVbx control ID from inside DialogBoxes

<oDlg> A reference to the DialogBox object container

<nClrFore>, <nClrBack> Colors of the oVbx from DialogBoxes

<WhenFunc> It is an expression to evaluate indicating if the control is or not enable.

<ValidFunc> An expression to validate when the control is going to lose the focus.

CLAUSES

DESIGN Allows the user to move and resize with the mouse

PIXEL To use pixel coordinates instead of Text coordinates.


Windows

Creating a new Window:

DEFINE WINDOW <oWnd> ;

[ FROM <nTop>, <nLeft> TO <nBottom>, <nRight> ] ;

[ TITLE <cTitle> ] ;

[ <color: COLOR, COLORS> <nClrFore> [,<nClrBack>] ];

[ OF <oParent> ] ;

[ BRUSH <oBrush> ] ;

[ CURSOR <oCursor> ] ;

[ ICON <oIcon> ] ;

[ MENU <oMenu> ] ;

[ STYLE <nStyle> ] ;

[ BORDER [ NONE | SINGLE ] ] ;

[ NOSYSMENU | NO SYSMENU ] ;

[ NOCAPTION | NO CAPTION | NO TITLE ] ;

[ NOICONIZE | NOMINIMIZE ] ;

[ NOZOOM | NO ZOOM | NOMAXIMIZE | NO MAXIMIZE ] ;

[ VSCROLL | VERTICAL SCROLL ] ;

[ HSCROLL | HORIZONTAL SCROLL ]

<oWnd> A reference to the Window Object.

<nTop> <nLeft> Window coordinates on screen. We simulate text coordinates.

<nBottom>, <nRight>

<cTitle> The title of the Window.

<oParent> A reference to the Parent Window.

<oBrush> An already created Brush Object to be used as background of the Window. Use DEFINE BRUSH ... to create it. This parameter is optional.

<oCursor> A reference to the Cursor Object to display over this control.

<oIcon> A reference to an Icon Object to be used by the Window. Use DEFINE ICON ... to create it. This parameter is optional.

<oMenu> An already created Menu Object. Use MENU ... ENDMENU inside a function as in examples. This parameter is optional.

<nStyle> A numeric value which indicates a special API style. [ Just for advanced FiveWin users.]

<nClrFore> The colors to use for the windows. They may be numeric RGB colors

<nClrBack> or xBase string colors.

Activating a Window

ACTIVATE WINDOW <oWnd> ;

[ ICONIZED | NORMAL | MAXIMIZED ] ;

[ ON LEFT CLICK <uLClick> ] ;

[ ON LBUTTONUP <uLButtonUp> ];

[ ON RIGHT CLICK <uRClick> ] ;

[ ON MOVE <uMove> ] ;

[ ON RESIZE <uResize> ] ;

[ ON PAINT <uPaint> ] ;

[ ON KEYDOWN <uKeyDown> ] ;

[ ON INIT <uInit> ]

[ ON UP <uUp> ];

[ ON DOWN <uDown> ];

[ ON PAGEUP <uPgUp> ];

[ ON PAGEDOWN <uPgDn> ];

[ ON LEFT <uLeft> ];

[ ON RIGHT <uRight> ];

[ ON PAGELEFT <uPgLeft> ];

[ ON PAGERIGHT <uPgRight> ];

[ ON DROPFILES <uDropFiles> ];

[ VALID <uValid> ];

<oWnd> A reference to the Window Object.

<uLClick> An action to be performed when the left button of the mouse is clicked over the Window.

<uRClick> An action to be performed when the right button of the mouse is clicked over the Window.

<uMove> An action to be performed every time the Window is moved.

<uResize> An action to be performed every the Window is resized.

<uPaint> An action, generally drawing action, to be performed every the Window is painted.

<uKeyDown> An action to be performed every a key is pressed being the Window focused.

<uInit> An action to be performed, generally some initialization, when the Window is being initialized.


What is FiveWin for Harbour ?

FiveWin for Harbour (FWH) is a set of commands, classes and functions developed with the objective to obtain the highest power from the Microsoft Windows environment in conjuntion with Harbour, the open source Clipper language compatible compiler (http://www.harbour-project.org).

FWH is a library that you may link to your Harbour built application enabling the use of all these functionalities. FWH includes a version built using Borland C/C++ 5.5 free compiler available from Borland downloads at (http://www.borland.com/bcppbuilder/freecompiler) and the same version also built using Microsoft Visual C++ (MSVC). You may decide which one do you prefeer to use. They work exactly the same.

FWH has been developed to keep total compatibility with the original FiveWin Library for CA-Clipper. FiveTech offers real compatibility between 16 and 32 bits. Due to this compatibility level both products share the same manual and most of the samples we provide.

The set of classes of FWH are completely self contained. FWH provides the needed classes to create MS standard Windows, Dialogboxes, Menus and Buttonbars with the Microsoft Office style, etc. The reasons why FWH has developed its own set of GUI classes are as follows:

· Full support of standard Windows resources: FWH allows you to use standard tools to design DialogBoxes, as Microsoft Visual Studio, Borland Resource Workshop, offering you the capability of use visual design in the same way as C and C++ professional programmers do. Designing your dialogboxes in this way allows you to keep a total independency between the graphic interface design in respect to your applications source code. You will be able to easily modify your dialogboxes without the need to alter or modify its related source code.

· FWH uses Borland C/C++ 5.5 own import libraries to access multiple Windows APIs so there is no need for a WinApi.lib (FiveWin for Clipper) equivalent. The same applies for MSVC.

Simple and easy to use: The FiveWin++ commands and class sets have been specially designed to offer a great ease of use and require a minimum learning curve. FiveWin has always been very popular for its power and easy of use.

These reasons show the enormous importance of using FWH to port your existing Clipper and FiveWin apps to 32 bits. FWH will give you total control over the Microsoft Windows environment, a must for any professional programming company that will allow them to deliver Windows applications that offer modern and updated management solutions.


Installing FiveWin for Harbour

FWH is designed to be used with Harbour (or xHarbour), the open source Clipper language compatible compiler available from www.harbour-project.org.

Though you may download latest build from that site, we strongly recommend to use the one we provide as it has been tested and it is already built containing its binaries files (harbour.exe) ready to be used.

Just click on the provided Harbour installtion icon and it will be automatically installed.


Using FiveWin for Harbour

Once you have installed Harbour, FWH and Borland C/C++ free compiler, simply go to c:\FWH\SAMPLES directory and review BuildH.bat defined paths to be sure they match with your Harbour and Borland installation selected paths.

Then type: BuildH.bat tutor01 (use BuildHM.bat for MSVC).

This should call Harbour.exe to compile tutor01.prg and call bcc32.exe to generate the required OBJ, call brc32.exe to generate the resources RES file if exists and finally call ilink32.exe to build the EXE.

This whole process is performed in an automatic way from BuildH.bat.

A first Hello World! Windows small dialog should shown on the screen.

If not, please review the paths inside BuildH.bat again to asure they are the ones you have selected for your Harbour and Borland compiler installation.

We do recommend to continue testing the different samples we provide on that directory.

To adapt your FiveWin and Clipper make files, simply do the needed modifications inside them as shown inside SAMPLES\BuildH.bat file.


Guidelines for Harbour users

FWH is contained into two libraries: FiveH.lib and FiveHC.lib. (Notice that FiveHM.lib and FiveHCM.lib are the MSVC versions).

Besides these, FWH provides an extensive set of header files (.CH extension) that implements all required xBase commands to create and manage all the different Windows objects.

In our samples directory ' \samples', we provide the file 'BuildH.bat' (BuildHM.bat for MSVC). This file shows the correct way to compile and link the applications developed with Harbour and FWH.

BuildH.bat:

if A%1 == A GOTO :SINTAX

if NOT EXIST %1.prg GOTO :NOEXIST

ECHO Compiling...

set hdir=c:\harbour\harbour

set bcdir=c:\bcc55\bin

%hdir%\bin\b32\harbour %1 /n /i..\include;%hdir%\include /p %2 %3 > clip.log

@type clip.log

IF ERRORLEVEL 1 PAUSE

IF ERRORLEVEL 1 GOTO EXIT

echo -O2 -e%1.exe -I%hdir%\include -tW %1.c > b32.bc

%bcdir%\bcc32 -M -c @b32.bc

:ENDCOMPILE

IF EXIST %1.rc %bcdir%\brc32 -r %1

echo c0w32.obj + > b32.bc

echo %1.obj, + >> b32.bc

echo %1.exe, + >> b32.bc

echo %1.map, + >> b32.bc

echo ..\lib\FiveH.lib ..\lib\FiveHC.lib + >> b32.bc

echo %hdir%\lib\b32\rtl.lib + >> b32.bc

echo %hdir%\lib\b32\vm.lib + >> b32.bc

echo %hdir%\lib\b32\gtwin.lib + >> b32.bc

echo %hdir%\lib\b32\lang.lib + >> b32.bc

echo %hdir%\lib\b32\macro.lib + >> b32.bc

echo %hdir%\lib\b32\rdd.lib + >> b32.bc

echo %hdir%\lib\b32\dbfntx.lib + >> b32.bc

echo %hdir%\lib\b32\debug.lib + >> b32.bc

echo %hdir%\lib\b32\common.lib + >> b32.bc

echo %hdir%\lib\b32\pp.lib + >> b32.bc

echo %bcdir%\lib\cw32.lib + >> b32.bc

echo %bcdir%\lib\import32.lib, >> b32.bc

IF EXIST %1.res echo %1.res >> b32.bc

%bcdir%\ilink32 -aa -Tpe @b32.bc

IF ERRORLEVEL 1 GOTO LINKERROR

ECHO * Application successfully built

ECHO

:LINKERROR

%1

rem if exist meminfo.txt notepad meminfo.txt

rem PAUSE * Linking errors *

GOTO EXIT

:SINTAX

ECHO    SYNTAX: Build [Program]     {-- No especifiques la extensi¢n PRG

ECHO                                {-- Don't specify .PRG extension

GOTO EXIT

:NOEXIST

ECHO Not exist the specified PRG

:EXIT

Please notice the use of Borland bcc32.exe (Borland C/C++ compiler), after calling the Harbour compiler, to generate the apropiate OBJ file to be linked with Borland free ilink32.exe.

More:


Important recommendations:

Please notice that Borland C/C++ 5.5 resources compiler (brc32.exe) requires to be called previously to call ilink32.exe, as the resultant RES file has to be provided to ilink32.exe. BuildH.bat clearly shows its use.

Do not use the Borland Resource WorkShop to save your 32 bit DLLs, it may corrupt them. Save your resources as '.RC' (ASCII) files, and then use the DLL\rc2dll2.bat utility to generate your 32 bits DLL:

Rc2dll32.bat <RCFile> à screens32.dll. Simply rename screen32.dll with the name you want.

If you keep all your resources in a DLL, it will be very easy to save them as an '. RC' file directly from the Resource Workshop, then use that '.RC' to link directly into your '.EXE', in case you want to store the resources inside the EXE, or use rc2dll32.bat to generate your 32 bits resources DLL.


Guidelines for Clipper and FiveWin users

All that is needed to rebuild you application in 32 bit form is to replace Clipper.exe and Blinker.exe calls with their 32 bit equivalents Harbour.exe, bcc32.exe and ilink32.exe as done from SAMPLES\BuildH.bat.

The FiveWin.ch header file automatically detects Harbour use and proceeds to perform the needed conversions.

The Harbour.exe compiler keeps compatibility with most of Clipper.exe flags.

The compatibility level of FiveWin source code with the new FWH is practically 100%. Review the fifth item in this documentation where we explain the steps to follow in detail.

if A%1 == A GOTO :SINTAX

if NOT EXIST %1.prg GOTO :NOEXIST

ECHO Compiling...

set hdir=c:\harbour\harbour

set bcdir=c:\bcc55\bin

%hdir%\bin\b32\harbour %1 /n /i..\include;%hdir%\include /p %2 %3 > clip.log

@type clip.log

IF ERRORLEVEL 1 PAUSE

IF ERRORLEVEL 1 GOTO EXIT

echo -O2 -e%1.exe -I%hdir%\include -tW %1.c > b32.bc

%bcdir%\bcc32 -M -c @b32.bc

:ENDCOMPILE

IF EXIST %1.rc %bcdir%\brc32 -r %1

echo c0w32.obj + > b32.bc

echo %1.obj, + >> b32.bc

echo %1.exe, + >> b32.bc

echo %1.map, + >> b32.bc

echo ..\lib\FiveH.lib ..\lib\FiveHC.lib + >> b32.bc

echo %hdir%\lib\b32\rtl.lib + >> b32.bc

echo %hdir%\lib\b32\vm.lib + >> b32.bc

echo %hdir%\lib\b32\gtwin.lib + >> b32.bc

echo %hdir%\lib\b32\lang.lib + >> b32.bc

echo %hdir%\lib\b32\macro.lib + >> b32.bc

echo %hdir%\lib\b32\rdd.lib + >> b32.bc

echo %hdir%\lib\b32\dbfntx.lib + >> b32.bc

echo %hdir%\lib\b32\debug.lib + >> b32.bc

echo %hdir%\lib\b32\common.lib + >> b32.bc

echo %hdir%\lib\b32\pp.lib + >> b32.bc

echo %bcdir%\lib\cw32.lib + >> b32.bc

echo %bcdir%\lib\import32.lib, >> b32.bc

IF EXIST %1.res echo %1.res >> b32.bc

%bcdir%\ilink32 -aa -Tpe @b32.bc

IF ERRORLEVEL 1 GOTO LINKERROR

ECHO * Application successfully built

ECHO

:LINKERROR

%1

rem if exist meminfo.txt notepad meminfo.txt

rem PAUSE * Linking errors *

GOTO EXIT

:SINTAX

ECHO SYNTAX: Build [Program] {-- No especifiques la extensi¢n PRG

ECHO {-- Don't specify .PRG extension

GOTO EXIT

:NOEXIST

ECHO Not exist the specified PRG

:EXIT

More:


Adapting your C source code:

Harbour requires some minor changes on your own developed C files.

We do provide an utility named TOOLS\Clp2Harb.exe that automatically performs those changes. Clp2Harb.exe is a Harbour small application and its source code is provided.

Clp2Harb.exe must be called prior to compile your C files:

Clp2Harb.exe <YourFile.c> temp\<YourFile.c>

Clp2harb.exe creates an output file with the name supplied as second parameter with the changes already implemented. Later on you call Borland bcc32.exe with the following syntax:

bcc32 -c TEMP\<YourFile.c>


Using Borland Custom Controls (Bwcc32.dll):

Instead of using the function LoadLibray(“Bwcc.dll”) like in Fivewin 16 bits, you must do the following:

BWCCRegister( GetResources() )

And place this at the bottom of your main PRG:

DLL32 FUNCTION BWCCRegister( hInst AS LONG ) AS WORD PASCAL LIB "BWCC32.DLL"


Using Advantage local RDD with Harbour:

Actually you can use Advantage client kit for 32 bits with Harbour to access remote or locally DBF files and their related indexes.

The remote access is based on the famous Advantage Xbase server which is also available to Clipper (16 bits) users, but the local driver is new to all Clipper users since it does not exist on 16 bits.

The local driver acts as a standard RDD against DBF files, so you can use it to develope your own applications with Harbour. The Advantage RDD suports CDX and NTX formats.

The Advantage local driver DLLs are present on a free software published by Extended Systems on their Web site and Fivewin for Harbour includes the necessary libraries to access these DLLs.

You may find the Advantage DLLs at the Extended Systems website located at www.extendsys.com, developers resources section. Once there, you will need to register yourself, then you will have access to them.

Then go the download area and select the most recent release.

This software includes all the needed libraries which are:

· ACE23.DLL: The 32-bit Advantage Client Engine.

· AXCWS32.DLL: The Advantage 32-bit communication layer for client/server access.

· ADSLOC32.DLL: The 32-bit Advantage Local Server.

· EXTEND.CHR: OEM collation sequences. This file is needed if OEM character sets re to be used with Advantage Local Server.

· ANSI.CHR: ANSI collation sequences. This file may be needed if ANSI character sets are to be used with Advantage Local Server.

· ADSLOCAL.CFG: The configuration file for Local Server.

All these files should be placed on the \WINDOWS\SYSTEM directory. In case you have a Advantage Database server then you will only need ACE32.DLL and AXCWS32.DLL

To use the Advantage RDD from your Harbour applications you just need to do the following:

Make a reference to file 'ADS.CH' on your PRG files when needed. Include in the link file the libraries rddads.lib and ace32.lib that came with Fivewin for Harbour package and request the Advantage RDD at the beginning of your application.

This is a little sample:

// FiveWin Quick browses feature sample

#include "FiveWin.ch"

#include "ads.ch"

REQUEST _ADS

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

function Main()

rddRegister( "ADS", 1 )

rddsetdefault( "ADS" )

SET SERVER LOCAL

SET FILETYPE TO CDX

USE Clientes // Open any DBF...

OrdSetFocus("DIRECCION") // Second Tag on Clientes.cdx

go top

Browse() // Quick browse!!!

USE

return nil

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

We highly recommend to use the Advantage remote Xbase Server from Extended Systems.


Steps to convert your applications from FW to FWC3

· As simple as replace clipper.exe with C3.exe in your make files. FW and FWC3 use exactly the same source code.

· To link your application you do need by now (as C3 soon will provide its own linker!), the Borland Tlink32.exe version whose download url is provided from www.c3compiler.com FWC3 provides a buildc3.bat file that easily and clearly explains the way to link your applications developed with C3 and FWC3.

· The resources (RC files) are 100% compatibles. You just have to use the resources compiler from Borland brc32.exe instead of rc.exe or Brc.exe. Borland Brc32.exe is included on all Borland products (C/C++, Delphi, ...).

· If you place your resources inside a DLL, then you must update those resources to a 32 bits DLL. FWC3 provides a batch file to easily create your 32 bits resources DLLs. Just open your actual 16 bits resources DLL using Borland Resources Workshop and save the resources as a .RC file. Then use our provided file to build the 32 bits version that automatically will place the resources into it.