Lescasse Consulting
 Home    Company    News    Prices    Download    Buy    Forums   
Read Me
Buy
Forums
Resume
AntiSpam 1.2
wBackup 1.11
NetAccess 2.0
Visual APL 1.0 
APL+Win 8.0 
APL+Win Products 
APL+Win Objects™ 
APL+Win Training 
APL+Web Services
APL+Web Component 
APL+ History
Dyalog.Net Tutorial
Conferences 
Powerpoint
White Papers
Web Hosting
References
Links
 
APL+Win Objects™ 6.0

TADO5
TADO5 Tutorial
TAPLDraw5
TAPLEdit5
TAPLSession5
TAbale5
TAboutBox5
TAccess5
TAgent5
TBlatMail5
TButton5
TCDO5
TCRC5
TCancelButton5
TCheck5
TCheckGroup5
TChildForm5
TChooseColor5
TChooseFont5
TClipBoard5
TClock5
TCodeStats5
TColors5
TCombo5
TComboDrive5
TComboFilter5
TComboList5
TComboTree5
TCommandBar5
TCommandButton5
TControlClass5
TCueCard5
TDHTML5
TDHTMLEditor5
TDateTime5
TDateTimeFr5
TDates5
TDemoHandlers5
TDisplay5
TDOS5
TDualSelect5
TEdit5
TEditAmount5
TEditDir5
TEditEnter5
TEditFile5
TEditGrid5
TEditList5
TEditListview5
TEditMenu5
TEditNum5
TEditSelect5
TEditSpin5
TEmail5
TError5
TExampleForm5
TExcel5
TExcel5 Tutorial
TFindReplace5
TFOne5
TFTP5
TFTP5 Tutorial
TFileCompare5
TFileMenu5
TFileMenuDef5
TFlatButton5
TForm5
TFormClass5
TFormEditor5
TFrame5
TGetDir5
TGif5
TGifForm5
TGifWb5
TGoMenu5
TGraphX5
TGrid5
TGridDisplay5
TGridPrint5
TGUID5
THLine5
THTML5
THTML5 Tutorial
THTTP5
THelp5
THelpMenu5
TImagelist5
TInfo5
TIniFile5
TInstall5
TInternet5
TJpg5
TJpgWb5
TLabel5
TList5
TListview5
TLock5
TLogs5
TMAPI5
TMath5
TMDIForm5
TMSOutlook5
TMaskEdit5
TMedia5
TMenu5
TMessage5
TModalCall5
TMsgBox5
TNavigator5
TNetwork5
TNonVisualClass5
TODBC5
TOKButton5
TObject5
TOpenFile5
TOption5
TOptionGroup5
TOutlook5
TOutlookMail5
TOWCSpread5
TPDF5
TPFKeys5
TPage5
TPassword5
TPicture5
TPing5
TPopupMenu5
TPowerpoint5
TPowerpoint5 Tutorial
TPrinter5
TProgress5
TProgressDlg5
TQuestion5
TRegistry5
TRegistryKey5
TResource5
TRichEdit5
TSPX5
TSQLDMO5
TScheduler5
TScroll5
TSelector5
TSpinner5
TSplitter5
TStatus5
TStopWatch5
TTest5
TTestError5
TTextFile5
TTimer5
TTip5
TTipForm5
TTLI5
TToolBar5
TToolbox5
TToolsMenu5
TTrackbar5
TTranslate5
TTree5
TVLine5
TViewMenu5
TWebBrowser5
TWebServer5
TWebSite5
TWebSiteNet5
TWinMenu5
TWord5
TYesNo5
    Visits:  2543 (11 on line) Last Update: Dec 4, 2003  
    Intro to APL+Win Programming with Fun    Printer Friendly  

APL+Win Programming Basics

In order to write Windows programs with APL+Win, you first need to get some basic understanding of how Windows is working.

Events Programming vs Procedural Programming

In Windows you are using an "Events Programming" scheme, while in DOS programmers were using "Procedural Programming".

Procedural means that your program is the Master who decides what happens: it executes its instructions in order and does not listen to your input while it is doing its processings. Sometimes it stops for requesting input from you and when you press Enter or click the mouse, it resumes execution, stopping listening to you again until the next input request.

Windows is very different: if you have used Windows at all, you may have noticed that Windows is always listening to you and reacting, sometimes with some delay, to everything you have done with your keyboard or mouse. This is because of the Events handling nature of Windows.

Under Windows the Master is no longer the program: it is you!

In order to achieve this, Windows programs have to be constantly listening to "events", even though they might sometimes be busy processing data at the same time.

An event is most often generated by the user, by pressing a key on his keyboard or moving or clicking his mouse. But, as will see later, there are many other possible sources of events.

When you develop a Windows application, the language you are using must be able to achieve this "events" listening and must be able to inform you when an event has occured. It must also provide you with all the necessary information concerning this event.

Your task as a Windows programmer is simply to react to each occuring event by writing a program (often a small program) which handles this event, i.e. which does the processing you have analyzed it should do when this event occurs.

APL+Win high and low level Windows tools

APL+Win is a pure Windows version of APL (the successor of APL*PLUS II and APL*PLUS III with which it is 100% compatible) and is an "events programming" language. It is a Windows language.

APL+Win offers you 2 ways of programming with Windows:

High level tools This is the simplest way, which we will describe in detail in this chapter. It implements high level Objects which you use in an Object Oriented manner, working with their properties, events and methods, pretty much as you would in such programming languages as Visual Basic and Delphi.
Low level tools APL+Win allows you to access the whole 16-bit and 32-bit Windows API (Application Programming Interface), i.e. the hundreds of functions and messages which are part of the Windows SDK (Software Development Kit). You can develop programs this way much as a C++ programmer would: using low level tools is much more tedious and difficult than using high level tools, but gives you access to everything Windows can do.

What is more, APL+Win lets you easily mix its high level and low level programming tools.

At the beginning, you will certainly mostly use high level tools and, as you gain more experience with Windows and develop more and more complex Windows applications with APL+Win, you might find that you also more and more often use the Windows API.

That's why this book will first concentrate on the high level Object Oriented tools built in APL+Win and then talk about the Windows API.

Objects, Properties, Events and Methods

In Windows, almost everything you see on the screen is an object.

A window is an object, a button is an object, a scroll bar is an object: list boxes, combo boxes, menu and menu options, toolbars, status bars, radio buttons, check boxes, etc. are objects.

All these things are called objects because just like real life objects, they have properties, events that can happen on them and actions that can be performed on them.

Let's take a pencil object: it has a size, a color, a brand written on it which are some of its Properties. Events can happen on it: it can for example be moved on the table surface or dropped on the floor. You can decide to put its cap on it and this is an action (in OOP terms: a Method which is applied to the pencil).

Similarly, a window has a size, a color and a caption (some title written on it) which are some of its Properties. When you drag it with the mouse, a Move event occurs on this window. When you resize it with the mouse, a Resize event occurs. If you decide to close the window by program, you would apply its Close method to it.

There are a limited number of objects in APL+Win, which almost all refer to standard Windows objects.

Each of these objects has built in properties, events and methods which you can use in your programs.

APL+Win Windows Functions

APL+Win contains the following system functions:

ŒWI Creates, controls and runs Graphics User Interfaces (GUI)
ŒWCALL Makes calls to Windows DLL
ŒWGIVE Allows you to yield the CPU to Windows during execution of a long runnning callback

and the following system variables:

ŒWSELF Contains the fully qualified name of the current Windows object
ŒWARG Contains the argument associated with an event or method, during a callback
ŒWEVENT Contains the name of the current event during a callback
ŒWRES Contains the explicit result, if any, that a Windows method or callback returns

for developing Windows applications.

The ŒWI system function

To work with high level Object Oriented tools, APL+Win provides you with the ŒWI system function.

This function does most of the work you need to write a Windows application.

Its syntax is:

result „ {object} ŒWI action {arguments}

Here are examples of all what it can do:

ŒWSELF„'object'ŒWI'New' 'obj_class' Create a new form or control
Example:
ŒWSELF„'fmTest'ŒWI'New' 'Form'
ŒWSELF„'fmTest.bnOK'ŒWI'New' 'Button'


result„ 'object'ŒWI'Method' Invoke a method
Method names always start with an uppercase character.
Example:
'fmTest'ŒWI'Close'
The result is most often 0 0½0 except for some methods like New, Close or Wait.
value „ 'object'ŒWI'property' Reference a property
Get the current value of one of the object's properties.
Example:
'fmTest' Œwi 'caption'
Property names start with a lowercase character.
'object'ŒWI'property' 'value' Set a property
Change one of the object's properties to a new value.
Example:
'fmTest'Œwi'caption' 'Test Window'
'object'ŒWI'event' 'callback' Associate a callback with an event
Example:
'fmTest'Œwi'onMouseMove' 'ŒWARG'
This means that every time the user will move the mouse over the fmTest window, the 'ŒWARG' expression will be executed.
result„'fmTest'Œwi'Wait' Wait on a form for user input
Example:
'fmTest'Œwi'Wait'
Every callback that is associated with an event is automatically executed when the event occurs.

Things will become much clearer through an example.

Let's write a Windows game with APL+Win! Yes, APL+Win is so simple that you already know enough to write a simple Windows game, with just a few APL instructions.

The Catch Me! game

The game consists of trying to click a button on a form with the mouse: however, every time the user moves the mouse cursor over the button, the button escapes. The user wins if he succeeds in clicking the button.

This game is an excellent way of explaining how to write a Windows application, what is an event and a callback, etc. Once we finish this example, you should be able to start writing simple Windows applications with APL.

First, we need a form. Every Windows application starts with a form.

Let's create one: we will call the form object: fmCatch.

      'fmCatch'Œwi'New' 'Form'

By default the form you just created is centered on the screen and is half the size of the screen in height and width.

fmCatch window

The New method returns as a result, the name of the object which has been created, here fmCatch.

You generally want to capture this result in the ŒWSELF system variable. When you do so, the current object becomes the one assigned to ŒWSELF and you may omit the ŒWI left argument when working on this particular object, until ŒWSELF is changed to some other object. Let's try it:

      ŒWSELF„'fmCatch'Œwi'New' 'Form'
ŒWI OBJECT ERROR: Object already exists
      ŒWSELF„'fmCatch'Œwi'New' 'Form'
                       ^

We get an error because the APL+Win system has a security which prevents you from creating an object having the name of an existing object. We must first destroy our fmCatch window. This is done by invoking its Delete method.

      'fmCatch'ŒWI'Delete'
      ŒWSELF„'fmCatch'ŒWI'New' 'Form'

Let us change a few properties of our form. First we need to reduce its size:

      ŒWI'size' 12 32

fmCatch window

An APL+Win form's size is by default expressed in screen number of lines and columns (which the standard Windows System font would use).

Let us change our window's title to "Catch Me!'. To do so, we need to assign a new value to the form's caption property:

      ŒWI'caption' 'Catch Me!'

fmCatch window with properties set

Our form immediately reflects the change.

If we wanted to check what is the current window's title, we would just need to do:

      ŒWI'caption'
Catch Me!

Up to now, it's pretty easy.

Note that we could have set one or more of our windows properties at creation time:

'fmCatch'ŒWI'Delete'
ŒWSELF„'fmCatch'ŒWI'New' 'Form'('size' 12 32)('caption' 'Catch Me!')

or, we could benefit from having assigned the result of the New method to ŒWSELF and written maybe more clearly:

     'fmCatch'ŒWI'Delete'
      ŒWSELF„'fmCatch'ŒWI'New' 'Form'
            ŒWI'size' 12 32
            ŒWI'caption' 'Catch Me!'

So, for now, our application contains at most 4 APL+Win instructions.

We need a button on the form. This button will be a "child" of the form and this is denoted by using a dot notation. Applying what we just learnt, we could write the following additional instruction:

  ŒWSELF„'fmCatch.bnCatch'ŒWI'New' 'Button'('caption' 'Catch Me!')

fmCatch window with bnCatch button

We have just define the entire user interface of our Windows game. We now need to react to a few events.

When the mouse cursor comes over the Catch Me! Button, we want to change its position in the form. In order to do so, we need to define a callback function for the MouseMove event on the Catch Me! button.

  'fmCatch.bnCatch'ŒWI'onMouseMove' 'fmCatch_bnCatch_MouseMove'

This instructs the APL+Win system that WHENEVER a MouseMove event occurs on the button (i.e. whenever the user moves the mouse cursor over the button), it must execute the fmCatch_bnCatch_MouseMove callback function.

You may ask yourself why I chose a so complex name for the callback function. You must understand now that a standard Windows application will contain a number of different forms, each of them containing a number of children objects (we call them "controls"), and that on each of these controls a number of events may occur for which you have decided to associate a callback function.

If your Windows application has 10 forms, each having 10 controls on each of which you want to handle 10 events, this means that your application will have 10x10x10 = 1000 callback functions!

The only way to not get lost in this "jungle" of callback functions is to adopt a strict naming convention for callback functions. The recommended naming convention consists of using the name of the object on which the event occurs, followed by the event name separated by underscore characters, hence here:

      fmCatch_bnCatch_MouseMove

I will however show you a better way of coping with callback functions at the end of this example.

We are left with writing our first callback function: fmCatch_bnCatch_MouseMove. The only thing we need to do in this function is to move the button to another location on the form.

By now, you might guess that moving the button is pretty easy: we only need to change its where property. However, we must ensure that the Catch Me! button stays inside the form: we must not set its where property to a location outside the form otherwise it would not be fair to the user!

The where property determines the top left corner position of the button, in terms of its y and x coordinates relative to the top left corner of the client area of the form. The button's where property must be larger than 0 and smaller or equal to the form size minus the button size.

So, here is our callback function:

    ’ fmCatch_bnCatch_MouseMove;A;B
[1]   A„'fmCatch'Œwi'size'              © get the form size
[2]   B„'fmCatch.bnCatch'Œwi'size'      © get the button size
[3]  'fmCatch.bnCatch'Œwi'where'(?˜A-B) © randomly change button pos
    ’

However, when an event is being handled by a callback function, the system has set the ŒWSELF system variable to the object on which the event occurs. This means that you may omit this object name in the left argument of ŒWI, whereever it appears in the function. The callback function therefore gets simplified to:

    ’ fmCatch_bnCatch_MouseMove;A;B
[1]   A„'fmCatch'Œwi'size'  © get the form size
[2]   B„Œwi'size'            © get the button size
[3]   Œwi'where' (?˜A-B)    © random change button position
    ’

You could even write this callback function in one instruction, as:

    ’ fmCatch_bnCatch_MouseMove
[1]   Œwi'where'(?˜('fmCatch'Œwi'size')-Œwi'size')
    ’

Callback functions are often very short in APL+Win, thanks to its high level object oriented tools, but remember that on the other hand a real Windows application may have hundreds or thousands of such callback functions.

Well, we are now ready to start our game!

In order to start a Windows application, we should invoke the Wait method on its main form (here fmCatch):

     'fmCatch'ŒWI'Wait'

The Wait method returns a value (0 by default), so it would have been better to use the following expression which absorbs the result since we do not need it for now:

     0 0½'fmCatch'ŒWI'Wait'

Just before doing so, let us summarize our programming efforts so far:

'fmCatch'ŒWI'Delete'
ŒWSELF„'fmCatch'ŒWI'New' 'Form'('size' 12 32)('caption' 'Catch Me!')
ŒWSELF„'fmCatch.bnCatch'ŒWI'New' 'Button'('caption' 'Catch Me!')
'fmCatch.bnCatch'ŒWI'onMouseMove' 'fmCatch_bnCatch_MouseMove'
0 0½'fmCatch'ŒWI'Wait'

which we can express it in a more readable manner in a simple function:

    ’ BookCatchMe1;Œwself
[1]   ©’ BookCatchMe1 -- Catch Me! game version 1.
[2]
[3]   'fmCatch'Œwi'Delete'
[4]   Œwself„'fmCatch'Œwi'New' 'Form'
[5]       Œwi'caption' 'Catch Me!'
[6]       Œwi'size' 12 32
[7]   Œwself„'fmCatch.bnCatch'Œwi'New' 'Button'
[8]       Œwi'caption' 'Catch Me!'
[9]       Œwi'onMouseMove' 'fmCatch_bnCatch_MouseMove'
[10]  0 0½'fmCatch' Œwi 'Wait'
    ’

and the following callback function:

    ’ fmCatch_bnCatch_MouseMove
[1]   Œwi'where'(?˜('fmCatch'Œwi'size')-Œwi'size')
    ’

Note the indentation in the BookCatchMe1 function which makes it more readable: APL+Win retains all blanks in source code, so do not hesitate to use blanks to indent lines, align comments, etc.

It's time to try our game:

      BookCatchMe1

Try to click on the Catch Me! button: every time you approach it, it escapes from you and it is quite difficult to catch it, isn't it?

fmCatch application

In fact, our game is not complete. We need a way to terminate it.

I suggest that, if the user happens to succeed in clicking the Catch Me! button, we change the button caption to something like 'Game Over!'.

Is that enough?

No, we also need to inhibit the onMouseMove event and callback function, otherwise the button would indicate Game Over! but would continue to escape from the mouse when the user moves the mouse on it.

Does all this seem difficult to you?

You might be surprised to see how simple it is with APL+Win.

Again, we need to react to an event, this time to a Click event on the Catch Me! button, so we need to associate a callback function to the button onClick event:

      'fmCatch.bnCatch'ŒWI'onClick' 'fmCatch_bnCatch_Click'

The callback function may be defined as:

    ’ fmCatch_bnCatch_Click
[1]   Œwi'onMouseMove' ''
[2]   Œwi'caption' 'Game Over!'
    ’

Remember that we do not need to specify the ŒWI left argument to fmCatch.bnCatch, since we are currently in a callback for this exact button (and therefore the system has set ŒWSELF to 'fmCatch.bnCatch').

The first instruction simply redefines the button MouseMove event as no longer having any callback function associated with it (the fmCatch_bnCatch_MouseMove stays in the workspace, but is no longer automatically called by APL+Win when a MouseMove event occurs on the button).

The second instruction sets the button caption to Game Over!.

Isn't it easy and fun?

Let's summarize what our programming efforts have been so far:

    ’ BookCatchMe2;Œwself
[1]   ©’ BookCatchMe2 -- Catch Me! game version 2.
[2]
[3]   'fmCatch'Œwi'Delete'
[4]   Œwself„'fmCatch'Œwi'New' 'Form'
[5]       Œwi'caption' 'Catch Me!'
[6]       Œwi'size' 12 32
[7]   Œwself„'fmCatch.bnCatch'Œwi'New' 'Button'
[8]       Œwi'caption' 'Catch Me!'
[9]       Œwi'onMouseMove' 'fmCatch_bnCatch_MouseMove'
[10]      Œwi'onClick' 'fmCatch_bnCatch_Click'
[11]  0 0½'fmCatch' Œwi 'Wait'
    ’

    ’ fmCatch_bnCatch_MouseMove
[1]   Œwi'where'(?˜('fmCatch'Œwi'size')Œwi'size')
    ’

and:

    ’ fmCatch_bnCatch_Click
[1]   Œwi'onMouseMove' ''
[2]   Œwi'caption' 'Game Over!'
    ’

Let's play our game:

      BookCatchMe2

the final fmCatch window in action

It is not so easy to catch the button: in fact it is even pretty difficult and this shows you how fast is APL+Win to react to events. You might even think that it is impossible!

However, here is a hint: wait until the button moves in the top left part of the form, then resize the form with the mouse to a much smaller form, where the button is still at least partly visible, now try again.

 This entire Web site has been dynamically generated by APL+Win Objects™ 6.0
 For all questions contact:  info@lescasse.com
 Copyright © 2003-2005 Lescasse Consulting. All rights reserved.