
(N.B. This text-version of the Manual has been extracted directly from the main Dr Wimp Manual,
which is prepared in Impression Publisher. Therefore some formatting anomalies are inevitable - and
graphics do not appear, of course. It is best viewed with a display width of about 110 characters.)

DO NOT ATTEMPT TO RE-FORMAT TO A DIFFERENT FORMAT WIDTH OR SOME TABLES AND PROGRAM LISTING EXTRACTS
MAY LOSE THEIR ALIGNMENT.



                                DrWimp

                Version 3.56 (01-August-2000)

 Andrew Ayre 1995, 1996, 1997, 1999 Changes/additions by Ray Favre from 1st May 1999 Major features
and updates by Guy Bartle Manual laid out by Eddie Lord

Public Domain (Freeware)

See Conditions of Use



Conditions of use

The DrWimp package is distributed on an As Is basis, without warranty. No liability can be
accepted  for any consequential loss or damage, however caused, arising from the use of this program
or other  utilities supplied. Boring but there you go.

The DrWimp library may be distributed for free and without the documentation, examples, utilities, 
etc. if it is being used in a Public Domain, Shareware, Cover Disc or Disc Magazine program. If you 
wish to distribute it with a commercial program then contact the author to negotiate royalties.

Public Domain libraries may make a reasonable charge for materials, handling, etc. as long as this 
does not exceed 2.00 (UK) net for this DrWimp package.

The DrWimp library may be reproduced in part if crunching and mangling utilities such as !BSquasher 
are used, otherwise it must be reproduced in whole, complete with the conditions of use and the 
copyright banner.

If the DrWimp library is being reproduced in full then it may be added to the !RunImage (or similar) 
file, and does not have to be separate.

The DrWimp package (apart from the 3rd party utilities as detailed in the !!ReadMe!! file) may only 
be distributed as a whole. For conditions of use of the third party applications see their own !Help 
files.

For distribution conditions of the DrWimp package as a whole and the files included in it which are 
not 3rd party, see the !!ReadMe!! file.

The author retains copyright of DrWimp, documentation and examples at all times.

The latest version of DrWimp can be obtained from the web page below or direct from:

  Email:        rayfavre@argonet.co.uk World Wide Web: http://www.argonet.co.uk/users/rayfavre/

Alternatively try your local PD library or send a HD disc and return postage to:

  Snail mail:   Ray Favre
                26 West Drayton Park Avenue
                West Drayton
                Middlesex
                UB7 7QA
                U.K.

Feedback such as suggestions for future additions, bugs and help requests for how to achieve various 
things are always welcome, either by E-mail or post.

From 1st May 1999 the support and distribution of the Dr Wimp package is carried out by  RayFavre. 

Andrew Ayre can still be contacted by email at: andya@earthling.net



Contents

Section 1 - Introduction

        1. Prologue     
        2. An overview  
        3. Handles      
        4. Variables & Strings  
        5. System variables     
        6. Security     

Section 2 - Tutorials

        Notes  
        1. Getting going        
        2. Menus        
        3. Windows      
        4. Window & icon control        
        5. Advanced menus       
        6. Panes        
        7. Save windows 
        8. Errors       
        9. Message files        
        10. Loading data        
        11. Interactive help    
        12. Sprite areas & Mouse pointers       
        13. The redraw process        
        14. Changing sprites & more on the iconbar icon 
        15. Large menus & rebuilds      
        16. Multitasking operations     
        17. Bars        
        18. Sliders     
        19. Loading & Saving Drawfiles  
        20. Rendering Drawfiles & Sprites       
        21. Validation Strings  
        22. Indirection 
        23. Text handling       
        24. Printing    
        25. Window & Icon creation      
        26. Stopping a desktop quit     
        27. Dynamic Areas       
        28. Colour Picker       
        29. Wimp messages
        30. Iconiser       
        31. Grubby tasks      
        32. Bits & bobs 
        33. Saving time 
        34. Final Comments      




Section 3 - Functions

        1. Misc 
        2. Polling      
        3. User 
        4. Windows      
        5. Messages     
        6. Icons        
        7. Menus        
        8. Sprites      
        9. Pointer      
        10. Drawfiles   
        11. Text        
        12. Printing    
        13. Dynamic Areas       
        14. Colour picker       

Section 4 - Index
        



Section 1 Introduction

1. Prologue

Ever wanted to write high quality multitasking programs? Cant quite get the hang of manipulating 
words, bytes, menu structures and message systems? Have you looked in despair at the amount of 
programming needed to get a single window on the desktop?

Forget all your worries and write superb applications with great ease; Doctor Wimp is here!

DrWimp - solves all your multitasking worries!

        The DrWimp system consists of:
             The DrWimp library.
             A skeleton blank application. 
             This manual in Impression Publisher and text format. 
             Text files with the history, upgrading and security information.
             Example Template files for standard windows.
             !Fabricate for quick blank skeleton application construction.
             Support files for the tutorials.
             !FuncnProc quick browser.
             !Linker BASIC library linker.
             !CodeTempsfor converting windows to code.
             Various PD utilities for compression and code security.
             Example applications written using DrWimp, with fully-commented code.


This Manual is aimed at getting you up and running with Dr Wimp. If you find you need more detail
and a wider scope then the charity book Dr Wimps Surgery (over  300 pages, A5 ring-bound) is
available from Ray Favre, whose address appears earlier.



2. An overview

Please note that although Version 3.55 of Dr Wimp is expected to work with  RiscOS Versions earlier
than 3.50, they will not be able to use the Colour Picker  wimp-functions - see Section 2.28. In
this manual all functions (FN) and procedures (PROC) will be referred to as just functions.

The file DrWimp (a Basic library) does all the detailed, clever work (and you leave it strictly
alone to  do that!) - and the !RunImage file is where you add the coding to control things from.

The DrWimp library is a collection of functions that you can call from the !RunImage file. All the 
function names in DrWimp are in lower case and preceded by wimp_ . For example:

PROCwimp_dosomethingamazing(curtain$)

Some of these functions in the DrWimp library need help from you and when they do they, in turn,
call  one of a number of functions which are defined in the !RunImage file, where you can easily
tailor the  DEF to your particular applications needs. All these functions in the !RunImage also
have lower case  names, but they are preceded by user_ . For example:

FNuser_givemesomehelp(tomato$)

From now on functions in the !RunImage file preceded by user_ will be referred to as user-
functions, and functions in the DrWimp file preceded by wimp_ will be referred to as wimp-
functions.

At the start, for a blank application which does nothing, all the user-functions will be empty and 
return default values if they are of the FN type. All the user-functions have to be in your 
!RunImage at all times, regardless of whether they do anything or not, otherwise your application 
might complain that one of them cant be found.

To save you having to type in the set of user-functions every time you write an application, there
is a  skeleton application called !MyApp. Inside !MyApp is a skeleton !RunImage file and its
matching  DrWimp library file - plus a !Run file and a !Sprites file. These therefore form the
starting point for all  new applications. Always start a new application from a copy of !MyApp -
preserving the original as a  master. (There is also the utility !Fabricate which will be introduced
later. This enables you to build a  rather more useful skeleton application automatically.)

Section 3 of this Manual - or the utility !FncnPrc (supplied in the Utils folder) - is a
catalogue of  all the user and wimp-functions, giving details what parameters you have to pass and
what is returned.  (!FncnPrc is also a demonstration of the DrWimp system, as it was written using
it. In particular the  ability to easily add panes to windows and saving files is demonstrated well
in this utility.)

The main difference that multitasking wimp programs have over the others, is that they are not
linear.  The program doesnt start at the top and work its way to the bottom. Instead, multi-tasking
programs  jump about depending on whether an icon has been clicked on, or a window dragged, or a
menu item  chosen, etc. All your application has to do is respond to these events when they
happen.

(The charity book Dr Wimps Surgery mentioned in Section 1.1 gives a detailed introduction to the 
multitasking Wimp environment.)


3. Handles

DrWimp allows windows (with or without icons) to be loaded into programs from a conventional 
templates file and this is the best way to do things at the start. (Dr Wimp also has wimp-functions
to  allow windows and icons to be created without templates - see later.) Menus are very easily
created using a wimp-function plus a shorthand reference in the !RunImage file.

Once you have loaded in a window or created a menu you need some way of getting at the information 
so you can put the menu on the screen, or change some of the window attributes, etc. The way this is 
done is by using handles, and they form a very important part of programming the Wimp.

When you load in a window, DrWimp asks the machine to reserve some memory to hold the window/ icon
definition(s) and to tell us the first memory address of that chunk. Once we have that start 
address, we can refer to it in future whenever there is a need to access the contents of that
particular  chunk of memory.

For example, if you load in a window called save, then you might tell Dr Wimp to put the first 
address of the reserved chunk of memory into an integer variable called save%. Thereafter, you can 
simply use save% as the reference to the start of the information about the save window i.e. save% 
becomes an effective handle to this window. You dont have to worry about the actual memory 
address, nor whats stored there. Normally you simply dont need to know it - it is safely held
within  save%.

The same thing applies to menus. When you ask DrWimp to create a menu from the shorthand that  you
supply, it gets a chunk of memory and fills it with the information needed for the Wimp to create 
the menu. It then tells you the start address of the memory chunk where it has put it i.e. the
menus  handle.

In general it is very wise to use handle names which remind you of what the handles are for. For 
instance, the handle for the main window of an application could be called Main%, and that for an 
iconbar menu IconbarMenu%, etc.

You will find that most wimp- and user-functions require a handle to a window or a menu to be passed 
to them, so you will need to use them a lot.

Look at the following piece of code (the functions will be described in more detail later on):

find% = FNwimp_loadwindow(Templates,find,0)
PROCwimp_openwindow(find%,1,-1)

The first line calls a wimp-function that loads in a window called find in a templates file called 
Templates. We can assume that it is a window for entering something to find. So, here, we have 
chosen find% for the variable name and the function returns the window handle (the address of the 
start of the memory block) to find%. From now on, whenever we want to do something with the  find
window, we simply use the variable find%.

The second line gives an example of how we use the handle. Here a wimp-function is being called that 
opens a window. Passed to it is the window handle, telling it which window to open (and some 
numbers regarding the positions to open it at).


The handle could have been called anything, eg:

coffee% = FNwimp_loadwindow(Templates,find,0)

Or changed later on, eg:

find% = FNwimp_loadwindow(Templates,find,0)
coffee% = find%

i.e. a handle is an ordinary Basic variable (of the integer type in this case).


4. Variables & Strings

One of the first lines of the !RunImage file should be something like:

LIBRARY <MyApp$Dir>.DrWimp

This tells the BASIC interpreter that you want to use a library (called DrWimp here) and where it
is  located. After this call, the two files (DrWimp and !RunImage) may be separate but they work as
if all  the code is in one file. Eg: you can call functions in DrWimp from !RunImage and DrWimp
calls  functions (the user-functions, in fact) in !RunImage.

More importantly, any variables or strings that are created in one of the files and isnt localised,
will be  available to both files, so either one can alter the contents of a variable etc. This could
cause problems,  because you could be using a variable in the !RunImage file, and then call a
wimp-function that also  uses it, so when the function is exited, the variable will be different
from what your code expects.

This problem has been largely overcome by localising most of the variables used in DrWimp.  However,
there are a handful of variables that cannot be localised for one reason or another (i.e. they  are
global variables). In the DrWimp library, all but two of these have been given names that start 
with a lower case w. So the simple rule is: when you create variable names yourself, dont start
them  with a w. It also follows that you must not change the values in any of the Dr Wimp
variables which have names  starting with w.

There are two global variables which have been designed to be changed by the programmer and do not 
follow the naming rule above. They are NULL% and UNUSED% and are both set to their default value  of
FALSE within FNwimp_initialise. The use of these variables by the programmer is covered  later - in
Section 2.16 and 2.29 respectively.

There is also a special global variable intended for use by the programmer when using the Colour 
Picker - but we can safely leave that until Section 2.28.


5. System variables

System variables help you in the important job of making sure that your application can run from 
anywhere, eg: floppy disc, hard drive, CD, etc, whilst still giving the application the essential
access to  files in the application directory, eg: templates, sprites, message files, etc. (In fact,
we met a system  variable MyApp$Dir in the LIBRARY line commented on at the start of the previous
Section.)

System variables differ from BASIC variables in that System variables are set from the command line 
using a star command or from within a Command or Obey file. Unfortunately it isnt very easy to read 
the contents of a system variable from BASIC programs. Because of this, DrWimp provides a wimp-
function (FNwimp_getsysvariable) to do this for you, and it will be described in more detail  later.

When the !Run file of your application is run (e.g. by double clicking) it sets up a system variable 
called Obey$Dir which contains the full pathname to your application directory. So if you have a 
file called Templates inside your application directory, then its full pathname can be written as 
<Obey$Dir>.Templates.

But if between your !Run file being run and your application loading in a file, another !Run file
from  another application is run, Obey$Dir will change. So, in your !Run file you must immediately
set up  a new, unique system variable as a copy of that previous Obey$Dir which can be used instead.

For example, if your application is called MyApp then you would probably use:

Set MyApp$Dir <Obey$Dir>

and then you would get access to your Templates file inside your application directory by using: 
<MyApp$Dir>.Templates.

System variables can also be used for other things. Eg: if you wrote a database application then you 
might have to set the maximum number of records allowed for the amount of memory that you have 
allocated. The limit could be put in the !Run file instead of the !RunImage file so non-programmers 
dont have to go and delve into your code. So you could have a line in your !Run file like:

Set MaxRecords 5000

Then in your !RunImage file you could read the value with something like:

MaxAllowed% = VAL(FNwimp_getsysvariable(MaxRecords))


6. Security

If you are going to distribute a new and brilliant application that you have slaved over for weeks,
then  you may want some security.

There are many ways in which you could give your code more security, and the following does the job 
well. (As an example, the total size for the source code for !Linker (!RunImage + DrWimp) was 55611 
bytes (54.3k). After being compressed and mangled the resulting (and much more secure) !RunImage 
was 8732 bytes (8.6k).)

All the utilities to do this are included with the DrWimp package and the procedure (as reproduced
in  the Security file) is:

1. Store your original RunImage somewhere safe. Link a copy of your RunImage with DrWimp using 
!Linker.

2. Compress the linked RunImage using !BSquasher (or another Basic compression utility).

3. Turn the linked and compressed RunImage into an absolute file by dropping it onto !MakeApp2 and 
saving under a different name.

3. Compress the result further by dropping it onto !Crunch, to give you your final RunImage to 
distribute.



Section 2 Tutorials

Notes

We would highly recommend using !TemplEd for editing/creating template files. It is very easy to use 
and it is included with DrWimp. Full instructions can be found in Manual inside the !TemplEd 
directory. However you can use any template editor you wish.

The tutorials use some support files and pre-made templates files. They can be found inside the 
tutorials folder. The template files contain standard windows like Info and Save windows. Feel free
to  use these in your programs (PD or commercial). There are no conditions attached to them.

This tutorial is meant to be worked through, step by step, with you at the keyboard. Before you
start,  make a copy of the blank application !MyApp to work on. Put it on a fresh disc or in a new
hard  disc directory.

If you get stuck or come across a problem then please, dont hesitate to get in touch. Your
information  could benefit other users.

Most learning is done through experimentation. In most of the tutorials, you will be invited to
fiddle  and generally muck about with the code. The worst that can happen through doing this is your 
application crashes and is quitted by the Task Manager.

To help you to understand further how to use DrWimp, some example applications are supplied with 
the DrWimp package, in the Examples directory. They have fully commented !RunImage files so you 
can study them.

A short list of what each demonstrates is given in the !!ReadMe!! file of each. 

(Note that these Example applications may not always be using the latest version of Dr Wimp. This 
does not detract from their usefulness as learning aids.)


1. Getting going

With your freshly-copied version of !MyApp visible in a filer window, double-click on it. Nothing 
should happen. But if you now open the Task Manager display and look at the list of tasks, you
should  see MyApp at the bottom. i.e. something did happen, the skeleton application is properly
loaded -  albeit with nothing to do.

Now load the !RunImage into !Edit (or your other favourite text editor) and take a look at what is 
happening. The first line of the !Run file (have a look at that as well) copies the system variable 
Obey$Dir into MyApp$Dir. Thus the LIBRARY command in !RunImage can be used with this  system
variable and, in effect, tells the computer that the DrWimp library is located within the  !MyApp
application directory.

The next line puts an application name into a string variable appname$ and this variable is used in 
several places later on.

The next line is in case of an error. All it does is call PROCwimp_error before making an orderly
exit and ending the application. This wimp-function will be  looked at in more detail later on.

 Note: don't add any lines between this error line and the following FNwimp_initialise line, as 
this could cause problems with the error handling.

The next line is very important and your application cant do anything until it has been called. It 
registers your application with the Task Manager and it returns a handle for your task. This has
been  put into task%.

task%=FNwimp_initialise(appname$,7000,300,0)

The first parameter is self-explanatory. Note that it is the text that will appear in the Task
Manager  window when the application is run, and can be anything. Try it and see - but not all of it
will be  displayed if it is too long. The Wimp automatically truncates appname$ if it is too long.

The second parameter specifies how much memory is to be reserved for window and menu definitions 
(including all the icons in the windows). For the moment it is just set to a largish value. When the 
application is finished you can reduce it to as low as possible consistent with the application
still  working fully. Earlier versions required you also to specify here the amount of memory to be
reserved  for indirected text (like indirected icon text, large menu entries and long window titles)
but from  Version 3,55 onwards this memory is measured and set aside automatically.

The third parameter is the minimum version number of RISC OS that the application is allowed to run 
on, multiplied by 100. The default is 300, so !MyApp will run on RISC OS 3.00 or better. (There is a
dilemma here: the Wimp actually needs the Wimp Version rather than the RiscOS Version - but we users
are more familiar with the latter. Using the RiscOS Version instead is not normally a problem
although there can be an inconsistentcy with RiscOS version 3.11. Dr Wimp tries to sort this out
behind-the-scenes but you are advised to use one of the main OS numbers, such as 300, 350, 370,
400.)

The fourth parameter tells Dr Wimp whether or not you want your application to respond to the 
desktop save protocol - 1 if you do, 0 if you dont. This is explained in more detail later and,
for now,  it is left set at 0.

One of the many things that FNwimp_initialise does is to call PROCuser_initialise,  which is
specifically intended for you to use for global variable declarations, window definitions,  menu
definitions and any other jobs that need or ought to be done before wimp-polling starts.

The final line of !RunImage before END (and the start of the !RunImage DEF PROC/FNs) calls 
PROCwimp_poll which makes it multitasking. This is a continuous loop until your application quits 
for some reason, such as Quit being chosen from the iconbar menu.

You may have been expecting more, but you will find that most of your applications will follow this 
same very short and simple pattern - needing no more than these few lines of main program. The rest 
of the !RunImage file is all the DEFs of the user-functions. They are all empty at the moment i.e. 
they do nothing or return default values. It is the filling of these which makes up the bulk of the 
programming effort for any application.

As was said, !MyApp doesnt do much at the moment and there is nowhere for the user to get access 
to it. So how and where do we start?

The best thing to do first is to add an icon to the iconbar.

So, in PROCuser_initialise, add the following line:

bar%=FNwimp_iconbar(!myapp,,0,1)

This function returns to bar% a handle for the window that contains the icon (i.e. a handle for the 
iconbar) and !myapp is the name of the sprite to use for the icon - which must exist in the
!Sprites  file of the application, as it does (have a look!). Try changing the sprite name to
!draw in the above  call and see what happens. (!draw is a sprite which will already exist on all
RISC OS computers. This  one doesnt need to be in your applications !Sprites file.)

The second parameter is the text to place under the icon (like the floppy drive icon). If it is an
empty  string (a null string) then no text is printed. Try entering some text and reload the
application.  Do  you see the difference on the iconbar?

We can leave the third parameter for now: just ensure that it is set at a small value - and 0 is a
good  idea. We will look in more detail at the use of this third parameter later - in Section 2.14.

The final parameter decides which side of the iconbar the icon appears - 0 for left and 1 for right.

You might like to try the variations and check their effects by running !MyApp again. Easy, isnt
it? (But you will only be able to quit the application from the Task Manager at the moment.)


2. Menus

What is needed next is a menu for the iconbar. Menus can be created by DrWimp in several ways but 
the simplest is by using a shorthand form which is passed as a string. DrWimp translates it into the 
correct layout in a block of memory for the Wimp to understand. After the FNwimp_iconbar, add  the
following line:

barmenu%=FNwimp_createmenu(MyApp/Info/Quit,0)

This creates a menu definition and returns a handle for it, which is put into barmenu%. The string
in  the first parameter is the key part and you can see that the string comprises three items of
text  separated by a /. Each item of text corresponds to an item in the menu-to-be. The first item 
(MyApp, here) is the menu title, and the following items are the actual menu items, in order.
Thus,  the top menu item is Info and the second (bottom) one is Quit. In the same manner you can
use as  many items as you wish - except that the total string length of the first parameter must not
exceed 255  characters. (Other means are provided to get round this limitation and are introduced
later.)

The second parameter is the maximum number of menu items allowed to be used in this menu - to  allow
for a later increase perhaps. It is set to 0 here and this has a special meaning: it just means that 
the maximum number of items in this menu is to be limited to the number used in the previous string 
i.e. two menu items, here.

At the moment MyApp doesnt know about the menu, all we have done is set up its definition in 
memory.

Here is where we first introduce one of the most powerful features of Dr Wimp and what sets it apart 
from being just another library. 

Using an application produced with Dr Wimp, whenever <menu> (the middle button) is pressed over a 
window belonging to the application (including the iconbar, which is a special window) the DrWimp 
library automatically calls the user-function FNuser_menu, defined in !RunImage. Moreover,  whenever
this call is made, the parameters in the user-function (window% and icon%) are  automatically filled
with the then-current appropriate values.

Thus, in our !MyApp example, if you press <menu> over the iconbar icon FNuser_menu will be  called
with the window handle (in window%) and the icon number (in icon%) over which <menu>  was pressed.
If we want to show a menu when <menu> is pressed over that particular window/icon  combination, then
we simply have to change DEF FNuser_menu to return the handle of the menu  that we want to open,
otherwise return a 0.

So, move down to DEF FNuser_menu in the !RunImage and change it to:

DEF FNuser_menu(window%,icon%)
Return%=0
CASE window% OF
      WHEN bar% : Return%=barmenu%
ENDCASE
=Return%

To ensure you understand the sequence of events properly in this first look at a user-function,
lets  detail what will now happen, step-by-step: i) The user presses <menu> over the iconbar icon;
ii) DrWimp automatically calls FNuser_menu with the parameter window% set to the  window handle
where the keypress took place. Here it will be the value held in bar%  (the iconbar window handle).
If <menu> was pressed over an icon, the icon handle  will also be set (in the parameter icon%) - as
well as the window handle. iii) DEF FNuser_menu has been altered by you to return the menu handle
barmenu%  (whose definition you have already created) when window%=bar%, so DrWimp  will receive
this returned handle and duly display the menu you want. In this iconbar case the value in icon% is
irrelevant but, in general as we will see, other CASE  statements could be added to pinpoint precise
window/icon combinations.

Using Dr Wimp, the user-functions are the main focus of the programmer and they all operate in a 
similar way to the one described above - so it is very important for you to understand their role. 

Try running the !MyApp application now. The iconbar menu will duly appear if <menu> is pressed  over
the iconbar icon.


OK, the menu is displayed, but selecting any of its items does nothing yet. Lets have a look at the 
Quit item.

When a menu item is selected, DrWimp calls another user-function: PROCuser_menuselection.  This time
it is a PROC, so nothing is returned. Instead you only have to act on the selection made by  the
user. As before, when the call to PROCuser-menuselection is made the current values of its 
parameters will automatically be placed in the parameter variables. If the Quit item is chosen,
what  will be passed are the handle of the menu that the user chose the item from (in menu%) and the 
number of the item chosen (in item%). The top-most item is number 1. 

In our example, the Quit item is 2 and the DrWimp library will therefore call 
PROCuser_menuselection(menu%,item%) with menu%=barmenu% and item% = 2.

So, change PROCuser_menuselection to look like:

DEF PROCuser_menuselection(menu%,item%)
CASE menu% OF
        WHEN barmenu%
        CASE item% OF
                WHEN 2 : PROCwimp_quit(0)
        ENDCASE
ENDCASE
ENDPROC

Calling PROCwimp_quit with an argument of 0 quits the application as soon as possible and if you 
now resave and run the application you can confirm that it does indeed work.

Try adding some more items when creating the menu. Dont forget to increase the 2 (the Quit
item)  in PROCwimp_menuselection accordingly though! For instance, try getting the computer to  make
a beep when you select one of the items. VDU7 would be ideal for this. Note that there is no  need
to change the last parameter (0) in FNwimp_createmenu (and we will return to this later). Menus may
also be created automatically from arrays and message files. See Section 2.9 for details.

Before moving on, note that displaying the menu and making a selection from it were handled by two 
independent programming actions. We were able to check that the menu was displayed OK before 
tackling what to do with it. This is typical of wimp programming: features are added by smallish
self- contained routines. This has considerable advantages for the programmer, who can (largely) 
thoroughly check one step before proceeding to the next - and go back and change one step with clear 
interfaces to the preceding and following steps.


3. Windows

Windows are, of course, the main visual tool of Wimp programs, so lets have a look at how Dr Wimp 
handles them. We will start with the very common info window.

An info window is usually accessed from the Info item on the iconbar menu. In the tutorials folder 
you will find the file Template1. Copy this into the !MyApp application directory and rename it as 
Templates. You can examine it if you want by loading it into !TemplEd. (At the moment, we will 
only be using windows which have been designed in a window template editor - such as !TemplEd, 
which is included in the package. A template editor puts its results into a templates file - and
one file  can hold several window definitions.)

In !MyApps !RunImage listing add the following line below FNwimp_iconbar (above 
FNwimp_createmenu):

info%=FNwimp_loadwindow(<MyApp$Dir>.Templates,info,0)

This wimp-function loads into the memory the definition of a window from the templates file, whose 
full pathname is given in the first parameter. The second parameter is the name of the particular 
window in the templates file. The last parameter  need not worry us too much at the moment but it
tells DrWimp where to find any  sprites that you may have used in designing the window. A 0 means
look in the Wimp sprite pool  (RMA), and this is the most common option. Alternatively, a handle
to a sprite area could be used  instead and would mean look in this sprite area (as well as the
RMA) As there are no sprites in the  info window (other than the borders/furniture built into
RISC OS) the last parameter  is irrelevant  here - but must still have a value and is set to 0.

The function FNwimp_loadwindow returns a handle for the window which we have assigned to the 
variable info% - whose name tells us what it is.

Now we need to modify the iconbar menu to take into account the info window. We want Item 1 of 
the iconbar menu to lead to this window, just like a sub-menu. This is very simple to do and, in
fact,  RISC OS (and Dr Wimp) allows submenus to be either normal submenus or windows. Using Dr 
Wimp, all you have to do is attach a submenu/window to the required menu item using a line such 
as: PROCwimp_attachsubmenu(barmenu%,1,info%)

So, add that line after the line with FNwimp_createmenu in it (the menu and the attachment need  to
exist before you can attach anything).

The first parameter of PROCwimp_attachsubmenu is the handle of the menu to which the  submenu is to
be attached: the second parameter is the particular item on that menu to which the  submenu is to be
attached (in this case 1 which is the top item) and the third parameter is the handle of  the
sub-menu to attach (or the handle of the window to attach). In this case it is the handle to the
info  window.

And thats it! Re-load !MyApp and you will now see that the first (Info) menu item now has the 
familiar arrow-head against it, indicating that a submenu/window is attached. If you move across
this  arrow-head the info window will appear.


You will see in the info window that the Author and Version fields have default information in them.
It  is very simple to change this, and the technique that we are about to describe can be used for
any icon  that has text, whether it is a Radio button, a default action button, or just a comment -
provided the  icon text is defined as indirected, (see !TemplEd). You only need to know the window
handle and the  icon number/handle. (You can find the icon number by loading the Templates file into
!TemplEd,  opening the info window and moving the pointer over the icon. The small !TemplEd window
at the  top right of the screen will give you the icon number.)

First of all we will look at the Author field. This is icon number three. Add the following line
just  before ENDPROC in PROCuser_initialise:

PROCwimp_puticontext(info%,3, Joe Bloggs 1996) Replace Joe Bloggs with your own name (there is
a limit on the length of the string though). This is  fixed by the indirected size and the physical
size of the box. These can easily be changed using  !TemplEd.

Now for the Version field. It is common practice to display the version number and date in the form 
X.XX (Dt-Mth-Yr), eg:

        1.42 (16-Oct-99)

Now add the following line just before ENDPROC in PROCuser_initialise (changing the date  to
whatever you wish):

PROCwimp_puticontext(info%,4,1.00 (29-Mar-98))

By now, you will see that the parameters to the function are quite simple. From left to right they
are:  the window handle, the icon number/handle, and the text to put into the icon.

 Note that it is important not to exceed the indirected string length set up in the icon definition
-  or you will lose the slabbed effect in the info box, and if you are using RISC OS 3.5+ the
desktop  font may revert back to the system font.

Check the application works as it is supposed to and then try using the same method to change the 
Purpose field to something more interesting!

By the way, as long as the window has been loaded, you can change icon text in the above fashion at 
any time. If the window is open when you do it the change will be displayed straightaway. If not,
the  change will show when you next display the window.


4. Window & icon control

Most applications have a main window that appears when the user clicks on the iconbar icon. This is 
very easy to implement with Dr Wimp.

Copy Template2 from the tutorial folder into the !MyApp application directory, and rename as 
Templates thus overwriting the previous one. Add the following line below  FNwimp_loadwindow to
load in a second window:

main%=FNwimp_loadwindow(<MyApp$Dir>.Templates,main,0)

Whenever the <select> or <adjust> mouse button is pressed over one of !MyApps icons, the user-
function PROCuser_mouseclick is automatically called, passing to it the window handle, the icon 
number, a number relating to the mouse button pressed and the work area coordinates the pointer was 
at. These are in window%, icon%, button%, workx% and worky% respectively. (It is useful to  remember
that PROCuser_mouseclick is used to respond to <select> or <adjust>, whereas  FNuser_menu is used
for <menu> presses)

Note:  PROCuser_mouseclick will also respond to mouse-clicks over a window's  work area, if the
latter is given a button type of Click in a template editor - see  !TemplEd. In such cases, the
icon number  passed in  PROCuser_mouseclick will  be -1.

In !RunImage, change PROCuser_mouseclick so it looks like:

DEF PROCuser_mouseclick(window%,icon%,button%,workx%,worky%)
CASE window% OF
        WHEN bar% : PROCwimp_openwindow(main%,1,-1)
ENDCASE
ENDPROC

As you can see, when a mouse button is pressed over the iconbar icon (i.e. in the window whose 
handle is bar%) then PROCwimp_openwindow is called , which here is used to open the window  whose
handle is main%.

The first parameter is the handle of the window to open. The second means open the window in the 
centre of the screen, and the third parameter means open it on top of all other windows.

If the second parameter was 0 then the window would open where you last left it (ie. before it was 
closed), or if it was being opened for the first time then it would open as it was positioned in the 
templates file. If the second parameter was 2 then the window would open centred on the mouse 
pointer. (Useful if you want to open save windows below the pointer so the user doesn't have to move 
the pointer very much to start dragging the file icon.)

If the third parameter was -2 then the window would open behind all the others. If the third
parameter  was -3 then the window would at the current stack position. Finally, if this third
parameter was another  window handle then the opening window would open behind that window - very
useful when panes  are involved (see Section 2.6).

Run !MyApp and check that it works, then try changing the parameters to PROCwimp_openwindow  and see
what happens. The window main% is divided up into three sections. We will use each section to
demonstrate one or  more aspects of icon control using DrWimp. The icon number for each icon can be
found by loading  the templates file into !TemplEd as described before.

The first section contains a writable icon (icon number 1) which can take up to 19 characters (+1 
terminator character, making a total of 20 - the set value here). This amount is set by using
!TemplEd  and changing the indirected icon size for the writable icon.

Entering text into writable icons is fully automated by the Wimp. Click in the icon and the caret
will  appear so you can enter some text.

What we want to do is enter some text and when Return is pressed, or OK is clicked on (icon number 
=2), the text is read from the icon and copied into the icon below (icon number 11).

The wimp-function FNwimp_geticontext reads text from icons. ie. it is the complement of 
PROCwimp_puticontext. The parameters passed are the window handle and the icon number.  The function
returns the text in a string. All that we need to do then is use  PROCwimp_puticontext to put the
text into the other icon.

So, alter PROCuser_mouseclick to look like:

DEF PROCuser_mouseclick(window%,icon%,button%,workx%,worky%)
CASE window% OF
WHEN bar%
PROCwimp_openwindow(main%,1,-1)
WHEN main%
  CASE icon% OF
  WHEN 2
    text$=FNwimp_geticontext(main%,1)
    PROCwimp_puticontext(main%,11,text$)
  ENDCASE
ENDCASE
ENDPROC

Re-load !MyApp and check that it works. Read this part of the above routine as When the window is 
main% and the icon is 2, read the text in icon number 1 and write it into icon number 11. The OK 
button (icon number 2) has the yellow trough/border around it and is called the Default Action icon.

Note that you can only put text into icons if they are what is called indirected. You can make an
icon  indirected by turning the option on when editing the icon in a template editor. At the same
time, you  need to decide the maximum number of characters you want to use - then add 1 to it (for
the  terminator). This is value is entered in the appropriate place in the template editor.

So, making an icon indirected with a value of 11 is enough for putting a filename (10 characters
plus  terminator) in that icon. Reduce the indirected value to as low as possible to save on memory.
If you  have an icon whose text you are never going to change during the program run (e.g. a label)
then you  can make it non-indirected to save memory - but note that the maximum size of
non-indirected text is  12 (11 characters plus terminator).

The above deals with clicking the OK button and now we have to get the Return key to perform the 
same action when it is pressed and the caret is in the writable icon (icon number 1). Pressing the 
Return key in this situation should always act the same as clicking on the OK button. Whenever a key
is pressed, FNuser_keypress is automatically called and passed to it is the  window handle and the
icon number holding the caret. Also passed to it is the ASCII number of the  letter/number/symbol
pressed, which for Return is 13.

Here are the key codes for the special keyboard keys:

Key             Alone           +Shift          +Ctrl           +Ctrl & Shift

Escape          &1B             &1B             &1B             &1B
Print (F0)      &180            &190            &1A0            &1B0
F1-F9         &181-189        &191-199        &1A1-1A9       &1B1-1B9
Tab             &18A            &19A            &1AA            &1BA
Copy            &18B            &19B            &1AB            &1BB
Left arrow      &18C            &19C            &1AC            &1BC
Right arrow     &18D            &19D            &1AD            &1BD
Down arrow      &18E            &19E            &1AE            &1BE
Up arrow        &18F            &19F            &1AF            &1BF
Page Down       &19E            &18E            &1BE            &1AE
Page Up         &19F            &18F            &1BF            &1AF
F10-F12       &1CA-1CC        &1DA-1DC        &1EA-1EC       &1FA-1FC
Insert          &1CD            &1DD            &1ED            &1FD    

In itsempty state FNuser_keypress returns 0. If we use the keypress to do something, then we  must
return a 1. This is to stop the keypress being passed onto other tasks by the Wimp.

So alter FNuser_keypress to:

DEF FNuser_keypress(window%,icon%,key%)
used=0
CASE window% OF
  WHEN main% 
    CASE icon% OF
      WHEN 1 
        IF key%=13 THEN
          text$=FNwimp_geticontext(main%,1)
          PROCwimp_puticontext(main%,11,text$)
          used=1
        ENDIF
    ENDCASE
ENDCASE
=used

Note that the writable icon is icon number 1, which is the location of the caret when Return is
pressed.

This is very similar to what we added in the mouse-click case - which is what you might expect as we 
want the same action. It may look to be a lot of code for what it actually does, but it has been
written  so that it is easy to add more pieces of code for lots of windows and icons, with the
minimum amount  of effort and minimum risk of problems. Also it encourages putting the code onto
several lines,  making easier to read. 


There is just one thing missing now. When you click on the OK icon it presses in briefly. When you 
press Return it doesnt. It is much more reassuring for the user to see it press in in both cases, 
because then they know exactly what has happened. Pressing in is simply a behind-the-scenes 
automatic trick whereby one iconshape/colouring is used for the un-selected state and another for 
the selected state.

DrWimp provides a wimp-function to select/unselect an icon. So to achieve our required effect all we 
have to do is select the OK icon, copy the text, then un-select the OK icon.

Alter the part between IF key%=13 THEN and ENDIF so that it looks like:

IF key%=13 THEN
  PROCwimp_iconselect(main%,2,1)
  text$=FNwimp_geticontext(main%,1)
  PROCwimp_puticontext(main%,11,text$)
  used=1
  PROCwimp_iconselect(main%,2,0)
ENDIF

Re-run !MyApp and check it works. 

PROCwimp_iconselect has three parameters (window%,icon%,state%). The first is the  window handle and
the second is the icon number. In this case it is 2 for the OK icon. The last  parameter controls
the selection/deselection. If it is a 1 then the icon is selected, and if it is 0 it is  deselected.
If you removed the second PROCwimp_iconselect then the OK button would stay  pressed in. Try it
and see! On fast machines the short press in may be too quick and just produce a flicker. You may
like to add  the following line just above PROCwimp_iconselect(main%,2,0):

PROCwimp_singlepoll

The use of that function is explained in a later section on multitasking operations (Section 2.16)
but  for now you can treat it in this case (and really only in this case) as a short delay.

Returning to our main% window, the second section contains two radio buttons labelled Choice1  and
Choice2 and an button labelled Swap. Both the radio buttons have the same ESG group (in one  ESG
group, only one radio button can be selected at once (see !TemplEd documents inside the  application
and the example application)), so clicking on one within the group de-selects any others in  the
same ESG group.  Thus, here, when the user clicks on Choice1 it becomes selected and Choice2 
becomes deselected, and vice versa. Also, here, if you press Swap the selected and de-selected
radio  icons swap over, as if you had clicked on the de-selected one. The Swap button has an icon
number  of 6.

If you write an application with radio buttons, you may have to keep track of which ones are
selected.  For !MyApp we will use choice% which will be either 1 or 2 depending on which radio
button is  selected. When you first load !MyApp we will have it so Choice 1 is selected, so we will
set  choice% to 1 at the start.

Although you can set the radio icon to select when editing the templates it is always best to do
this in  your program so there is no chance of it falling over if a user fiddles with the templates
file. In fact,  this is good practice for all initial settings. When Swap is clicked on, we look
at choice% to decide which to select and which to de-select.

Just before ENDPROC in PROCuser_initialise, add the following lines:

choice%=1
PROCwimp_iconselect(main%,4,1)
PROCwimp_iconselect(main%,5,0)

After PROCwimp_puticontext(main%,11,text$) in PROCuser_mouseclick, before the  ENDCASE, add the
following:
    
  WHEN 6
    IF choice%=1 THEN
      PROCwimp_iconselect(main%,4,0)
      PROCwimp_iconselect(main%,5,1)
    ENDIF
    IF choice%=2 THEN
      PROCwimp_iconselect(main%,4,1)
      PROCwimp_iconselect(main%,5,0)
    ENDIF
    choice%+=1
    IF choice%>2 THEN choice%=1
  WHEN 4 : choice%=1
  WHEN 5 : choice%=2

It is mostly self explanatory. The sequence choice%+=1:IF choice%>2 THEN choice%=1  toggles choice%
between 1 and 2 to keep track of which one is selected.

This middle section of the main% window is a bit over-the-top, but it is a good demonstration of 
selecting and de-selecting radio icons.

There is a small problem with radio buttons. Try pressing <adjust> over a selected one. You will
find  that it becomes deselected. Having none of the radio buttons selected may be an undesirable
situation.  It is quite simple to solve this.

If you have a look at PROCuser_mouseclick you will see that the third parameter is called  button%.
Basically, if button%=4 then <select> was pressed. If button%=1 then <adjust> was  pressed. There
are also numbers for combinations of mouse buttons, but we need not concern  ourselves with that at
the moment.

Alter the WHEN 4 and WHEN 5 parts so they look like:

WHEN 4
  IF button%=1 THEN PROCwimp_iconselect(main%,4,1)
  choice%=1
WHEN 5
  IF button%=1 PROCwimp_iconselect(main%,5,1)
  choice%=2

Re-load !MyApp and make sure that you now always have a radio icon selected.

 Note: the act of clicking on a radio icon with any mouse button will automatically deselect the 
others in the same ESG group, so thats why we only set the icon clicked on with <adjust> and  not
deselect the other here.


The last section of the main% window has an option icon and two buttons. What we want to do with 
this section is control the option icon using the buttons, in much the same way as for the radio
icons.  There is a difference though, in that at any one time, we will want to disable (grey out)
one of the  buttons - because, for instance, if On is already chosen there is not much point in
clicking on On . If  the user clicks on a disabled icon, then the mouse click is ignored, and
PROCuser_mouseclick is  not called.

So, just before ENDPROC in PROCuser_initialise, add the following:

option%=0
PROCwimp_icondisable(main%,10)

option% records the state of the option icon, so if the application ever needed to act upon its
state, it  could just look at option%. The function disables (greys out) the Off button (icon
number 10). Its  complement PROCwimp_iconenable enables icons and has the same parameters.

So, modify PROCuser_mouseclick to:

WHEN 5
  IF button%=1 THEN PROCwimp_iconselect(main%,5,1)
choice%=2
WHEN 9
  PROCwimp_icondisable(main%,9)
  PROCwimp_iconenable(main%,10)
  PROCwimp_iconselect(main%,8,1)
  option%=1
WHEN 10
  PROCwimp_iconenable(main%,9)
  PROCwimp_icondisable(main%,10)
  PROCwimp_iconselect(main%,8,0)
  option%=0
WHEN 8
  IF option%=0 THEN
    PROCwimp_iconenable(main%,10)
    PROCwimp_icondisable(main%,9)
  ENDIF
  IF option%=1 THEN
    PROCwimp_icondisable(main%,10)
    PROCwimp_iconenable(main%,9)
  ENDIF
  option%=ABS(1-option%)

You should be able to see how it works, and know exactly what will happen when you click on the 
icons. Run it and check.

Using PROCwimp_icondisable and PROCwimp_iconenable you can disable/grey out and  enable any icon you
wish. 

As you can see, PROCuser_mouseclick is probably one of the most important functions and  will often
contain most of the code to control you application.



You must have noticed in many applications (eg. !Edit, !Draw) that as soon as you have some unsaved 
data, the title of the window has an asterisk added to its end. Using DrWimp this is quite easy to 
achieve, once you know that you have some unsaved data..........

 Note: In order to change the window title it must be indirected. This is set up using a template 
editor like !TemplEd, similar to setting up indirected text for icons.

For !MyApp we will assume that we have some unsaved data when, in the main% window, OK or  Return
is pressed.

FNwimp_getwindowtitle returns a string containing the window title and its complement is 
PROCwimp_putwindowtitle which changes the title to the supplied string. All we have to do  therefore
is read the title, add  * to the end and put it back.

So change the WHEN 2  section in PROCuser_mouseclick to:

WHEN 2
  text$=FNwimp_geticontext(main%,1)
  PROCwimp_puticontext(main%,11,text$)
  r=1
  title$=FNwimp_getwindowtitle(main%)
  IF RIGHT$(title$,2)= * THEN r=0
  IF r=1 THEN PROCwimp_putwindowtitle(main%,title$+ *)

The existing title is read into title$ and checked to see if * has already been added (we dont 
want to add  * each time OK is pressed!). If it hasnt then the asterisk is added. You should
now be  able to alter a part of FNuser_keypress so the title changes when Return is pressed as well.

If your program has a save feature (details on how to do that coming up later) then when the data
has  been saved you can remove the asterisk from the title.

Dont forget to allow for the extra space-plus-asterisk (two characters) when setting the maximum 
allowable length of the indirected title text!


Just a quick thing for you to try while we are dealing with windows: quite a few programs have a 
temporary window that appears in the centre of the screen when it loads. It stays there for a bit
before  closing again. This is called a banner. Using banners is a good way of announcing your
program or reminding people to register it. DrWimp  has a function that handles banners for you.
While the banner is on the screen, you can still use the  desktop and your application.

This is how you use it: Just before ENDPROC in PROCuser_initialise enter the following line:
PROCwimp_banner(info%,3)

When you load !MyApp, the info window will appear for three seconds in the middle of the screen. 
The info window isnt really suitable, so you can design your own window, load it in, and put things 
like version number and date, etc in using PROCwimp_puticontext.


Finally in this section, it is worth mentioning that you may want to give the input focus to a
window  you have just opened ( i.e. the title bar changes to a cream colour). As has been
demonstrated, this is  done automatically by using PROCwimp_putcaret to place the caret into a
writable icon in the  window. However, there may be occasions when one of your windows will not have
a writable icon  and/or you want to give it the input focus more specifically.

This is effected very simply by calling PROCwimp_putcaret with the appropriate window handle  and
the icon parameter set to -1. This gives the window the input focus without placing the caret.


5. Advanced menus

So far we have only got a simple two-item menu with an info window leading, like a sub-menu, from 
Item 1. (Windows used as sub-menus are often called dialogue boxes). There is a lot more you can 
do with menus. This part looks at submenus, ticks, greying out, dotted lines, changing menu text,
and  writable menu items.

First of all, lets create a menu for our main window. Just below the existing FNwimp_createmenu 
line, add the following lines:

menu$=MyApp/Info/Item 2/Item 3/Item 4/Save
mainmenu%=FNwimp_createmenu(menu$,0)
PROCwimp_attachsubmenu(mainmenu%,1,info%)

And attach the menu to the main window by altering FNuser_menu so it looks like:

DEF FNuser_menu(window%,icon%)
Return%=0
CASE window% OF
        WHEN bar% : Return%=barmenu%
        WHEN main% : Return%=mainmenu%
ENDCASE
=Return%

When you press <menu> anywhere over the main window, you should get a menu with 5 items. The  first
item should have a small arrow-head to the right of it - showing that it leads to a submenu. ( In 
fact, as we have said, it can be a sub-menu or a window - just supply the appropriate handle.) In
this  case we have attached the info window.

Now create another menu by adding the following line above the menu$=... you have just entered:

i3menu%=FNwimp_createmenu(Item 3/Help/Tick me!,0)


You can see from the title of this menu that it is obviously a submenu for Item 3 on our main menu. 
Here is how to add it: instead of entering a window handle to the submenu attaching function, you 
simply enter a menu handle. For example, immediately below 
PROCwimp_attachsubmenu(mainmenu%,1,info%), add:

PROCwimp_attachsubmenu(mainmenu%,3,i3menu%)

Run !MyApp and take a look at the menu. And that is all there is to it!


Here is another example of how easy Dr Wimp is to use.

Before the i3menu%=... line add the following:

tickmenu%=FNwimp_createmenu(Tick me!/Bored/Dull/Waffle,0)

And after the i3menu%=... line add:

PROCwimp_attachsubmenu(i3menu%,2,tickmenu%)

Thus you can see that it is quite painless to build up very complex menu structures.


As you have seen before, if you choose a menu item then PROCuser_menuselection is called. If you
choose the first item from the menu tickmenu%, then the parameters placed in  PROCuser_menuselection
will be: menu%=tickmenu% and item%=1.

When you first create a menu, it will have no ticks by the side of any items, no dotted lines
separating  items, and none of the items are greyed out. Any that need to be done when the
application loads, have  to be set up after the menu has been created.

PROCwimp_menutick toggles a tick next to the menu item specified. Add the following line to the  end
of PROCuser_menuselection and try it out:

IF menu%=tickmenu% AND item%=1 THEN PROCwimp_menutick(menu%,item%)

PROCwimp_menudisable and PROCwimp_menuenable surprisingly enough enable and disable  menu items!

At the end of PROCuser_menuselection, add the following lines and try it out:

IF menu%=mainmenu% AND item%=2 THEN PROCwimp_menudisable(menu%,3)
IF menu%=mainmenu% AND item%=4 THEN PROCwimp_menuenable(menu%,3)

PROCwimp_menudottedline(menu%,item%) puts a dotted line on the menu below the item  specified. Try
it out by adding the following after i3menu% is created:

PROCwimp_menudottedline(i3menu%,1)


There are still a few more functions related to menus!

Look at:

PROCwimp_menupopup(menu%,pos%,x%,y%)

This wimp-function is designed to allow you to bring up a menu without the need to press <menu>. So 
you can use it to bring up a menu from a <select>/<adjust> mouse-click, or at any time you wish.

The parameter pos% controls the positioning of the menu:
    
    If pos%=0, then the menu menu% is displayed at the co-ordinates x%,y% .

    If pos%=1 then the menu is positioned as for an iconbar menu (as if the iconbar icon was at x%).
    
    If pos%=2 then the menu is centred on the screen.
    
    If pos%-3 then the menu is placed at the mouse pointer position (slightly to the right, to line
up with the use of the ptr_menu pointer shape usually used with menu icons).

These options can be useful for many purposes. (For instance, a menu icon is often used - usually
to  the right of a writable icon - to offer the user a choice of items/strings to enter into the
writable icon.  The use of pos%=3 would be ideal here.)

Note that, for some values of pos%, the values of x% and/or y% are ignored, but it is vital that
dummy  x%/y% values are still used in these cases.


The text of a menu item can be read by using FNwimp_getmenutext, passing the menu handle and  the
item number. The complement of this is PROCwimp_putmenutext. This allows you to change  the text of
an item. The text can be up to 78 characters wide, so if you dont know the length of the  string
then truncate it possibly by using some sort of code like LEFT$(....,78).

Now, delete the previously-entered PROCwimp_menudisable and PROCwimp_menuenable  lines, and put the
following lines in the same place:

IF menu%=mainmenu% AND item%=2 THEN
  PROCwimp_putmenutext(mainmenu%,3,ABCDEFGHIJKLMNOPQRS)
ENDIF

Try choosing the second menu item with <adjust> (to keep the menu displayed). The menu will 
automatically adjust its width to accommodate the longest line.


The last major menu function turns an item into a writable one. A block of memory is reserved to put 
the text into it automatically. After the main menu has been defined, add the following line:

PROCwimp_menuwrite(mainmenu%,4,20)

The first parameter is the menu handle, the second is the item number. The third parameter is the 
maximum length of text allowed to be entered. It doesnt matter if some text is already there: it
will be  reinserted into the writable icon (and, if necessary, the maximum length of text will be
increased to  allow all the existing text to be entered). To read the text, simply use
FNwimp_getmenutext.

The final handful of menu functions dont really need much description. For more details see 
!FncnPrc or Section 3 in this manual.

FNwimp_menusize                 - Returns the number of items in a menu.

PROCwimp_menuclose              - Closes any open menu.

FNwimp_getmenutitle             - Returns the title of the menu.

PROCwimp_putmenutitle           - Changes the menu title.

PROCwimp_menuitemcolour         - Sets the colour of a menu item text.

Tip: If you are using a standard iconbar menu, with Quit as its last item, you can use:

WHEN FNwimp_menusize(info%) : PROCwimp_quit(0)

instead of:

WHEN 2 : PROCwimp_quit(0)

in the earlier coding. This will ensure that the quitting action will always be associated with the
last  item on the menu, however many items there are. This is very useful when you are developing a 
program and changing the number of menu items.

Finally, you might wish to know that Dr Wimp creates all the title and item text in menus as
indirected.  This should be a transparent feature but it may help if/when you examine the coding in
the DrWimp  library.


6. Panes

Using DrWimp, it is very easy to attach a pane to a window. From the tutorials folder, copy 
Template3 into the !MyApp directory and rename as Templates.

Where the other windows are loaded in, load in the window pane:

pane%=FNwimp_loadwindow(<MyApp$Dir>.Templates,pane,0)

The pane is to be attached to the main window. 

When a window is dragged about, it is actually being continually re-opened all the time. This means 
that PROCuser_openwindow is also being called continually just before the window in question is 
opened.

So, to effect a pane, every time the main window is opened we want to first open the pane in the 
window stack position that is supplied. Then, by telling DrWimp that the window has a pane using 
FNuser_pane, the main window is opened below the pane.

To show this, in PROCuser_openwindow, first add the following lines:
    
   IF window%=main% THEN
     xoff%=x%-FNwimp_getwindowsize(pane%,0)
     PROCwimp_openwindowat(pane%,xoff%,y%,stack%)
   ENDIF
   
The pane also needs to be closed when the main window is, so in PROCuser_closewindow add  the
following line:

IF window%=main% PROCwimp_closewindow(pane%)

Then change FNuser_pane as follows, to tell DrWimp that the window has a pane:

DEF FNuser_pane(window%)
Return%=0
IF window%=main% THEN Return%=pane%
=Return%

Re-load !MyApp and check that it is working. And that is all there is to it!


Just a quick explanation of a few other related things:

PROCwimp_openwindowat opens a specified window so that the top left corner is at the co- ordinates
x%,y%. If you want the window to open on top, then stack% = -1, or at the bottom if  stack%=2. If
you want the window to open behind a certain one, then stack% = the handle  of the window to open
behind.

If you want a window to open with another one but not follow it around the screen, then in 
PROCuser_openwindow, use PROCwimp_openwindow. If you set the second parameter to 1  then it will
continually re-centre, so it is best to set it to 0. Also, just pass stack% straight through.

Multiple panes are easily achieved. Add the following line to load in a second pane:

pane2%=FNwimp_loadwindow("<MyApp$Dir>.Templates","pane2",0)

Now, we have to consider more carefully the order of the window stack.

When you have one pane you look to see where the Wimp is going to open the window in the stack 
(stored in stack%), then first open the pane in that stack position. DrWimp then sees that the
window  has a pane so opens the window behind the pane. This is what we have done so far.

With two panes you have to decide which one is going to be top-most, with the second pane behind 
that, followed by DrWimp opening the window behind the second pane (this can be extended to as  many
panes as you like).

We are going to make DrWimp open the second pane behind the current pane, so change the section in 
PROCuser_openwindow to:

IF window%=main% THEN
  xoff%=x%-FNwimp_getwindowsize(pane%,0)
  PROCwimp_openwindowat(pane%,xoff%,y%,stack%)
  yoff%=y%-FNwimp_getwindowsize(main%,1)
  PROCwimp_openwindowat(pane2%,x%,yoff%,pane%)
ENDIF

So we have the first pane opening in the stack position, then the second pane is opened below the
first  pane, but in order to get DrWimp to open the window below the second pane we have to change 
FNuser_pane to return the handle of the bottom-most pane (the second one):

IF window%=main% THEN Return%=pane2%

Change the relevant parts in PROCuser_closewindow so when the
main window is closed both  the panes close and check it all works:

IF window%=main% THEN
  PROCwimp_closewindow(pane%)
  PROCwimp_closewindow(pane2%)
ENDIF

 Note that you can attach panes to any window, so you could have a window with three panes and 
another with one, etc, but be careful not to attach panes to panes!  Note also that, with Dr Wimp,
there is no real need to define a pane as a pane in its window  definition e.g. there is no need
to choose the pane option in the Edit window window, although  it does no harm to do so.


7. Save windows

Adding and controlling save windows is very easy. Copy the file Template4 from the Tutorials 
folder into !MyApp and rename as Templates. Load in the save window:

save%=FNwimp_loadwindow(<MyApp$Dir>.Templates,save,0)

and after PROCwimp_attachsubmenu(mainmenu%,3,i3menu%), add:

PROCwimp_attachsubmenu(mainmenu%,5,save%)

If you run !MyApp now, the save window will behave like any other window that hasnt got any code 
to tell it what to do. Everything starts to work when you change FNuser_savefiletype as  follows:

DEF FNuser_savefiletype(window%)
Return$=
IF window%=save% THEN Return$=FFF
=Return$

DrWimp now knows that save% is a save window and that it saves text files. Don't try it just yet as 
DrWimp will try to filetype the saved file and it is not created, so will throw up an error.

When the file icon in the save window is dragged to a destination, FNuser_savedata is called.  This
is where you do the actual saving. path$ is the full pathname of the file that you are saving to 
(the destination file) and window% is the handle of the window that the icon was dragged from (the 
source file).

You will notice that FNuser_savedata contains the following lines:

LOCAL ERROR ON ERROR LOCAL =2 These lines allow DrWimp to respond if an attempt is made to save to a
protected floppy disc or a  locked hard drive. It is suggested that they be REMed out until your
saving code works properly so  that errors are reported to you. Any local variables should be
declared before these lines, and the rest  of your saving code after them.

Dont always assume that the pathname in path$ will be something like  ADFS::Gromit.$.TextFile. It
could be a system variable that the Wimp expands to a full  pathname later on. So, enter the
following into FNuser_savedata:

IF window%=save% THEN
  file%=OPENOUT(path$)
  BPUT#file%,This is a text file,
  BPUT#file%,created by MyApp.
  CLOSE#file%
  PROCwimp_menuclose
ENDIF

 Note: the filetyping is taken care of by DrWimp as a result of the FNuser_savefiletype  action
earlier. FNuser_savedata returns a number. This can be a 1 or a 0, or a 2 if an error. Make sure you
return  a 1 if some data is saved (it is very important that you do this), otherwise return a 0.

The parameter values allow you to do some checking in FNuser_savedata before deciding  whether to
save or not - depending on the results.

For example at the start of FNuser_savedata, you could check to see whether the file path$  exists.
If it does then use FNwimp_errorchoice to allow the user to decide whether to overwrite  the file or
not. If they decide not to then return a 0, otherwise save the file and return a 1.

You can now drag the icon to the filer or other applications. The standard error messages like You 
must drag the icon to a filer window to save... are taken care of by DrWimp.

(FNuser_savedata and its parameters can be used for other purposes associated  with file dragging
and having nothing to do with saving. Dont forget, if you dont  actually save any data, return a
0)

It is very easy to add lots more save windows. Simply load them in, add them to a menu (or provide 
some way the user can get to them), return their filetype from FNuser_savefiletype, and do the 
saving in FNuser_savedata.

A rather neat trick that can be performed is to open windows as menus. You can see the effect if you 
add the following to the bottom of PROCuser_menuselection:

IF menu%=mainmenu% AND item%=5 THEN
  MOUSE X,Y,B
  PROCwimp_menupopup(save%,0,X,Y)
ENDIF

Now select the save item from the save menu. You will see that the save window opens and stays open 
until you complete the save or click elsewhere.

You may have noticed that some save windows have a rather attractive looking border around the file 
icon. Impression is an example of this, but there is a small potential complication as you will see. 
Change the line where the save window is loaded in to:

save%=FNwimp_loadwindow(<MyApp$Dir>.Templates,nicesave,0)

so a different template is used for the save window. Now run !MyApp and try using the save window 
now. You will probably get an error and the application will quit.

The reason is that the icon numbers in the save window are very important to Dr Wimp and nicesave 
uses different icon numbers to our previous one. Loading the templates into TemplEd you will see
that  the icon to be dragged is now icon number 3, where it was 0 in the old save window.

PROCuser_saveicon is used to tell DrWimp the three key icon numbers in each save window. The 
default values are:

0 for the (draggable) file icon, called drag% 1 for the writable icon, where the filename or
pathname goes, called write% 2 for the OK button, to click on to save to the pathname, called ok%

So if you are using a modified save window - e.g. like nicesave  - then you must set new icon 
number values. So add the following line to PROCuser_saveicon:

IF window%=save% THEN drag%=3:write%=1:ok%=2

Reload the application and check that it works. (Icon numbers 1 and 2 did not actually alter in our 
example, so there was no need to change them. But it has been done to demonstrate exactly how.) You 
simply set these icon numbers to whatever you have used in your window template and this action 
overrides the default values. 

PROCuser_saveicon is a little different in that it works rather like a FN, because it  can return
values. But whereas a FN can only return one, PROCuser_saveicon can  return three values by using
the RETURN keyword in front of each of the three variables  drag%, write% and ok% in its DEF line.



8. Errors

If you get an error or you are trying to debug a program, error windows can be very useful. They can 
tell you (and the users of your application) information while the program is running.

Error windows can be altered quite a bit, so there are several parameters needed to bring one up.

There are two wimp-functions for error windows:

PROCwimp_error(title$,error$,button%,prefix%)

This one is the most common.

title$  is the title of the window. This is usually the application name. error$  is the error
message itself. The text is wordwrapped automatically. button%  controls the default button. If it
is 1 then you get an OK button. If it is a 2 then  you get a CANCEL button instead. prefix%        
allows you to tailor the title to suit the error message. If prefix% is 0  then the title is title$.
If it is 1 then the title is prefixed with Error from . And if  it is 2 then the title is prefixed
by Message from .

The other function is:

FNwimp_errorchoice(title$,error$,prefix%)

 The parameters act in exactly the same way as for PROCwimp_error. This function displays an  error
window with both an OK button and a CANCEL button. If OK is clicked on then the  function
returns a TRUE (-1). If CANCEL is clicked on then it returns a FALSE (0).

Error messages have their limitations. For instance, they stop processing from happening, so your 
multitasking application and all others stop until you respond to the error window button(s).



But what if you want more than two buttons, or alternative text in buttons? It is possible to use a 
window of your own to report an error, but how can you force the user to acknowledge it? Standard 
error windows grab the pointer and refuse to let it go, and so can you using Dr Wimp with your own 
custom-built error windows.

To see this, add the following line where the other windows are loaded:

error%=FNwimp_loadwindow("<MyApp$Dir>.Templates","error",0)

which will load a customised window called error. Then add this line after WHEN 8 : in  PROCuser_
mouseclick;

PROCwimp_openwindow(error%,1,-1)

and this line between the two ENDCASE statements at the end of the same procedure:

WHEN error% : IF icon%=1 THEN PROCwimp_closewindow(error%)

Add this line just before the ENDPROC in PROCuser_openwindow;

IF window%=error% THEN PROCwimp_bindpointer(error%)

and this line just before the ENDPROC in PROCuser_closewindow:

IF window%=error% THEN PROCwimp_releasepointer

Save the changes and run !MyApp again. Clicking on the Option button in the main window  generates
a home made error window which grabs the pointer until OK is clicked.


To summarise what has been done here: opening the error window calls PROCwimp_bindpointer,  which
traps the pointer inside the named window. As the pointer cannot escape, there is no point in 
having any window tools apart from a title bar. Closing the window calls  PROCwimp_releasepointer,
which frees the pointer again.


It may assist you in your programming and debugging to know a little about the errors/warnings 
which are deliberately trapped by the Dr Wimp library. An attempt has been made to distinguish 
these by the title text used in their error message display. There are less than a dozen such
traps  within the DrWimp library. They concern the following areas:

  RISC OS Version - fatal error if OS Version is less than that specified in  FNwimp_initialise. Error
message title will be Error from WIMP

  Window/icon indirection - fatal error if attempt is made to change window title or icon text  when
they are not defined as indirected. Error message title will be Error from  <YourAppName> library

  Saving data - DrWimp passes on any Abort on data transfer type Wimp error (probably  fatal). Error
message title will be Message

  WimpSlot increase - Non-fatal warning if whole of requested increase cannot be done. Error  message
title will be Message from <YourAppName> library

  Printing - Printing abort Wimp error messages passed on (non-fatal).  Error message title  will be
Error from <YourAppName> library

  Dynamic areas - Two fatal Wimp errors if you try to change a dynamic area that does not exist or if
the change cannot happen for some reason.  Also, one non-fatal error if you try to delete a dynamic
area which does not exist. Error message titles will be Error from <YourAppName> library

  Directory path - Non-fatal warning if FNwimp_getdirectorypath is called for a string  that does not
contain a . character. Error message title will be Message from  <YourAppName> library


You will, of course, get other error/warning messages arising from your own use of  PROCwimp_error
and FNwimp_errorchoice and you may feel it worthwhile to arrange for  their error message titles to
be suitably unique - to make them easily distinguished from the above.

Inevitably, you will also get error messages which do not fall into the above categories - and these
will  be picked up by Line 70 of the skeleton !RunImage of !MyApp, which ensures that the error
message  title will be Error from <YourAppName> and that they will all be fatal. They may be the 
result of your own programming errors or, possibly, due to a bug in Dr Wimp (which you are urged to 
report if you feel this is the case).


9. Message files

It is getting increasingly common for applications to have Message files (nothing to do with the 
Wimps messaging system!). These files have most of the text for the application in. So, for
example, it  can be easily translated into another language by someone who doesnt need to know
anything about  programming.

Copy the Messages file from the tutorial folder into the !MyApp directory. Load it into !Edit and 
have a look at it.

Comments start with a hash #. Lines which have text on to be used in the application start with
what  is called a token. This is just a few letters that the line can be identified by. The token
and the text are  separated by a colon. For example: LIB:Doctor Wimp

If we wanted to use the line of text Doctor Wimp then we would reference it by using the token 
LIB.

 Note: The message file must be terminated by a Return, otherwise the last message in the file 
will not work.

Lines of text can also have strings inserted into them when they are read into the application. For 
example:

VER:1.00 (%0-%1-99)

When you read in this line, you supply two strings. These could be 29 and Mar for example.  When
the line is read in it ends up as 1.00 (29-Mar-99).

PROCwimp_initmessages(path$) sets up blocks of memory ready to read in the lines of text.  path$ is
the full pathname to the Messages file.

In PROCuser_initialise, call the function for the Messages file inside the !MyApp directory.

To read a line without substituting any strings you can use FNwimp_messlook0(token$). This  returns
the line of text.

To read a line and replace %0 with a string you can use FNwimp_messlook1(token$,a$),  where %0
in the messages file is replaced with a$.

To read and substitute two strings you can use FNwimp_messlook2(token$,a$,b$). Add the  following
lines after PROCwimp_initmessages and run your application. When you have  checked that it works you
can delete the lines:

lib$=FNwimp_messlook0(LIB)
PROCwimp_error(appname$,LIB=+lib$,1,2)
os$=FNwimp_messlook1(OS,3.11)
PROCwimp_error(appname$,OS=+os$,1,2)
ver$=FNwimp_messlook2(VER,29,Mar)
PROCwimp_error(appname$,VER=+ver$,1,2)


Message files can also be used for creating menus - see Section 2.15


10. Loading data

This is very simple to do. Whenever a file (or directory or application) is dragged and dropped
onto a  window belonging to your application (or, indeed, just double-clicked on), then
FNuser_loaddata  is called. This is the user-function where you add code to do the actual loading
into a block of memory  or an array etc. The parameters of FNuser_loaddata are:

path$   is the full pathname of the file to be loaded (the source file). Dont always assume  that
it is something like : IDEFS::Andy.$.TextFile window% is the window handle. (It will be 0 if the
file was double-clicked rather than  dragged.) icon%   the icon number that the file was dropped on
to.  (It will be -1 if the file was double- clicked rather than dragged.) Most of the time you would
only need to check the  window handle, but the icon handle can be used for drop-boxes. These are
boxes  with text in saying something like: Drop file to load here. ftype$  is the filetype of the
source file. Eg: for text files it is FFF. Files have a three  character hexadecimal filetype, but
directories are 1000, and applications are  2000. workx%,worky% is the window window% work area
coordinates that the file was dropped at.  (These will both be -1 if the file was double-clicked on
rather than dragged.) If you decide to load in the file after looking at all the parameters, then
you must load it in and return a  1. This is so DrWimp can send a message to the filer or any other
application that the file came from,  saying that it has been loaded. (As with FNuser_savedata,
FNuser_loaddata can be used for  other useful purposes without actually loading a file - then
returning 0.)

Here is an example piece of code for loading in a text file in FNuser_loaddata

DEF FNuser_loaddata(path$,window%,icon%,ftype$,workx%,worky%)
used%=0
IF ftype$=FFF THEN
        file%=OPENIN(path$)
        L%=1
        REPEAT
                A$(L%)=GET$#file%
                L%+=1
        UNTIL EOF#file%
        CLOSE#file%
        lines%=L%-1
        used%=1
ENDIF
=used%

What this does is to load a text file into an array called A$ (which you will need to create in 
PROCuser_initialise). At the end, lines%= the number of lines read in.

Try altering !MyApp so it can load in a text file, then using the save box, allow the user to save
the  text file to somewhere else. All you have to do is alter the save code so it saves the array.

Files can also be loaded in with double-clicks on the file. They can be made to load in your
application  first, if it isn't already. The only thing you need to add to achieve this is a line
like the following in  your !Run file:

Set Alias$@RunType_000 Run <Obey$Dir> %%*0

Change 000 for the filetype you are using, eg. FFF for text files. Beware though, when a file is 
loaded in this way, the parameters window% and icon% passed to FNuser_loaddata will be 0  and -1
respectively. The work area coordinates will be set to -1. See above.

You may wish to give your filetype a name. Eg. to give the filetype &000 the name TestFile put a 
line like the following in both your !Run file and !Boot file:

Set File$Type_000 TestFile


11. Interactive help

DrWimp supports interactive help applications like Acorns !Help. There are two facilities: one for 
windows and icons, and one for menu items.

For windows/icons, all you have to do is return the help string for a given window handle and icon 
number in FNuser_help. Enter the following lines into FNuser_help, reload !MyApp, load  !Help, and
move the pointer over the info window and the iconbar icon:

DEF FNuser_help(window%,icon%)
h$=
CASE window% OF
  WHEN info% :
  CASE icon% OF
    WHEN 1 : h$=This application is called MyApp 
    WHEN 2 : h$=It tests the DrWimp library
    WHEN 3 : h$=MyApp was written by Joe Bloggs
    WHEN 4 : h$=This is the version number and date
    OTHERWISE : h$=This is the MyApp info window.
  ENDCASE
  WHEN bar% : h$=This is the MyApp icon.
ENDCASE
=h$

Similarly, for menu items, use FNuser_menuhelp, eg:

DEF FNuser_menuhelp(menu%,item%)
h$=
CASE menu% OF
  WHEN barmenu% :
    CASE item% OF
      WHEN 2 : h$=Click <select> to quit"
    ENDCASE
ENDCASE
=h$


12. Sprite areas & Mouse pointers

All the sprites in the windows we have used so far are from the Wimp sprite pool and we have 
displayed them in icons. However, we may wish to display icons in other ways and to do this Dr Wimp 
allows an application to create its own (private or user) sprite areas - which are stored in the 
wimpslot, the memory used by the application. This has the advantage that when the application quits, 
all the memory is regained. We will use the phrase user sprites to describe sprites that are held in 
such a sprite area.

FNwimp_loadsprites does all the work for you and must be called (in a certain simple but strict 
way) before loading in any windows that use user sprites. Passed to it is a pathname to a sprite file 
and a pointer/handle to the memory space to load the sprites into. The sprites in that area can then be 
used in windows (you set the last parameter of PROCwimp_loadwindow private sprite area handle) 
- or to change the mouse pointer shape, see next.

PROCwimp_pointer controls the mouse pointer shape over windows i.e. which sprite is used for 
the pointer when in one of your applications windows. Briefly, you can change the pointer sprite 
between the Wimps default pointer sprite held in the RMA sprite pool and a user sprite. The details 
are demonstrated below. (You can also change the pointer shape when over an icon, independently of 
the window. This is also covered below.)

Copy the file Sprites from the tutorials folder into the !MyApp directory. Enter the following lines in 
PROCuser_initialise:

size%=FNwimp_measurefile("<MyApp$Dir>.Sprites")
DIM sprites% size%
a%=FNwimp_loadsprites(<MyApp$Dir>.Sprites,sprites%)

a% is an arbitrary variable not being used elsewhere globally. Note also that the second parameter of 
FNwimp_loadsprites is the handle/pointer to the memory location to hold the sprites. This 
loading sequence is very important and a little unusual. It is explained in more detail later.

Whenever the pointer moves in and out of one of !MyApps windows, the functions 
PROCuser_enteringwindow and PROCuser_leavingwindow are called.  So, in 
PROCuser_enteringwindow, add the following lines:

IF window%=main% THEN
  PROCwimp_pointer(1,sprites%,ptr_hand)
ENDIF

And in PROCuser_leavingwindow, add the following:

IF window%=main% THEN
  PROCwimp_pointer(0,0,)
ENDIF

Run !MyApp and you should find that when you move the pointer over the main window, it turns into 
a hand.

The first parameter of PROCwimp_pointer tells DrWimp whether to use the Wimps default 
pointer (0), or a user-defined one (1). The second parameter tells which sprite area is to be used, 0 for 
the Wimp sprite pool, or a handle for a user sprite area.

The Wimps default pointer is held in the RMA, so both the first and second parameters should be 0 to 
use it. If you wish to use a user-defined user sprite instead, the the first two parameters should be, 
respectively, 1 and the private sprite area handle holding the sprite you want.

The last parameter is the name of the sprite to use and it only has relevance for the user-defined 
pointer. If you are using the Wimps default pointer, then the string will be ignored. (But you need to 
put something there and a null string  is a good idea.)


You may have noticed that the pointer changes into one looking like a caret when it is over a writable 
icon. This is effected via the icons validation string - see !TemplEd. For example, in the validation 
field of  a writable icon you will probably see:

R7;Pptr_write

This particular validation string shows two Commands: an R-command and a P-command, separated 
by a semi-colon. The P-command specifies a sprite (which must be in the Wimps sprite pool) to be 
used for the pointer when over the sprite and ptr_write is the name of the sprite which is a thin 
vertical red line - the caret. (R7 describes the particular border given to the icon.)

Note: if you want to experiment here, dont forget to ensure that you load both lo-res and hi-
res sprites into the Wimps sprite pool.

You can do similar things with other icons like the menu icons. Impression has some good examples. 
See the section on validation strings (Section 2.21) for more details.



The method for loading in a sprite file may seem a bit strange, especially the idea of passing the 
handle of the user sprite area to the function, instead of it returning it to you. This is the same 
arrangement as used for loading in drawfiles, and allows one block of memory to hold more than one 
sprite/draw files, each with their own handles.

Things might become a little clearer if you look at the following example code to load in two sprite 
files:

size%=FNwimp_measurefile("<MyApp$Dir>.Sprites1")
size%+=FNwimp_measurefile("<MyApp$Dir>.Sprites2")
REM** Note the += above.
DIM sprites% size%
sprites1%=sprites%
sprites2%=FNwimp_loadsprites(<MyApp$Dir>.Sprites1,sprites1%)
a%=FNwimp_loadsprites("<MyApp$Dir>.Sprites2",sprites2%)

This sequence first measures both the sprite files whose paths are shown, adding the size of the second 
to the first. Then DIM is used to create a block of memory big enough to hold both files. A handle is 
chosen (sprites1%) for the first sprite file and is given the value of the DIMmed block.i.e. the 
block is effectively renamed sprites1%. The name of the block can now be forgotten.

The final two lines load in the sprite files one at a time - with the loading action returning the 
starting point in the block for the next sprite i.e. the pointer/handle of the next sprite. The last 
parameter of FNwimp_loadsprites is the handle of the sprite file being loaded in, and returned is 
the handle to the next sprite file to be loaded into the same block. We thus end up with a number of 
sprites loaded into one defined area of memory, but with discrete pointers/handles to each sprite.

As we measured the total size needed before we started the loading action, the handle returned by the 
last call of FNwimp_loadsprites cannot be used for anything, so is just put into an arbitrary 
variable and forgotten about.

This sequence can be used for any number of sprite files, of course. It is not difficult but it obviously 
needs to be adhered to strictly.

Finally, the number of sprites in a sprite file can be obtained with FNwimp_countsprites, and the 
name of a sprite in a sprite file can be returned with FNwimp_getspritename.



13. The redraw process

As you will already have seen, if you have a window where all the action takes place in icons, the 
Wimp automatically does all the updating for you when you open/move/update the window. However,  if
your window has some graphics/text plotted straight onto the window background (which we will  call
user graphics) then the Wimp needs your help to draw/redraw them when necessary. For  example, you
could be using the CIRCLE command to draw a circle in a window.

The Wimp asks for help by asking you to redraw all or part of the user-graphics whenever needed. 
Mostly, redrawing is necessary every time a window is moved/scrolled etc., because moving/scrolling 
a window on the screen is done by successively deleting and re-opening it.

It is vital to note that, in order for the redraw process to work, the window must  have its
auto-redraw flag unset in the template editor.

When the Wimp wants a redraw, it calls PROCuser_redraw automatically. In its parameters, the  handle
of the window is passed, plus the position of the rectangle on the screen that needs to be  redrawn.
The rectangle works like a graphics window created with VDU 24, so you can redraw all the  window
contents if you like (although that can sometimes be a bit slow) and anything outside the  rectangle
will be clipped.

The Wimp redraw process is a powerful tool in many applications - both for display and printing -
and  this introductory manual cannot do it justice. Its use is covered in detail in the charity book
Dr  Wimps Surgery, mentioned in Section 1.1.



14. Changing sprites & more on the iconbar icon

If you have an icon which holds a sprite (such as the file icon in a save window) then you can
change  it to another sprite by using PROCwimp_puticontext. This will only work however, if the icon
is  indirected which is set up using a template editor. (The iconbar sprite can be changed using 
PROCwimp_iconbarsprite - see below.)

For example, insert the following line just before ENDPROC in PROCuser_initialise:

PROCwimp_puticontext(save%,0,file_ffd)

(If you are using the nicesave template, the second parameter should be 3, not 0.)

Re-load !MyApp and the file icon in the save window will now be the standard one for Data.


This also is a good place to revisit:

FNwimp_iconbar(sprite$,text$,maxlen%,position%)

which we introduced briefly very early on in this tutorial - in Section 2.1. You will recall that we
have  so far set text$ to a null string and maxlen% to 0 - and the resulting iconbar icon has always
been  a sprite-only icon i.e. with no text beneath it.

By using other values for the second and third parameters, we can put text underneath the sprite on
the  iconbar and also arrange for this text to be indirected - with a maximum length determined by 
maxlen% - so that we can change it during the program run if we wish e.g. change the iconbar text 
to Loaded when file data has been dragged to it and loaded.

Firstly, it is vital to remember that the value you set in maxlen% will only come into effect if
text$  is not set to a null string. (In fact, a null string triggers the action in the DrWimp
library to create a  sprite-only result.)

If you want a sprite-plus-text iconbar icon then a typical FNwimp_iconbar call might be:

iconbar%=FNwimp_iconbar(!myapp,MyApp,5,1)

and the result on the iconbar will be ...............
                                                                              

Here, the second parameter contained text which is 5 characters long and we matched this in the
value  of the third parameter. (Dr Wimp automatically adds one for the terminator character.) The
text is  centred on the sprite.

But things are a little more clever than this. Firstly, if the value set in maxlen% is less than the
length  of text set in text$, then maxlen% will automatically be increased to the length of text$. 
Secondly, if the value set in maxlen% is greater than the length of text set in text$, then the 
iconbar text space created will be sufficient to display text of this greater length i.e. ready for
you to  change the text up to this greater length later in the program. Finally, if you do not want
the initial iconbar icon to show any text but you want to add some later,  then simply use something
like:

iconbar%=FNwimp_iconbar(!myapp, ,5,1)

Note that the second parameter is not a null string but, rather, is a string with a space character
in it.  The result will be an iconbar icon with (centred) space beneath it for up to 5 characters
(plus  terminator) for you to use later in the program.

Just a couple of pieces of practical advice here:

- try not to use an iconbar text length which extends much beyond the width of the sprite used, 
otherwise the result looks somewhat ungainly on the iconbar. - If your text consists of all wide
characters (e.g. W) then it is possible that the displayed  result on the iconbar might be clipped
slightly at each end. If this occurs just increase  maxlen% until the display is right. (And dont
forget that the iconbar icon has its own wimp-functions for changing its text and its icon- 
PROCwimp_puticonbartext and PROCwimp_iconbaricon respectively.)



15. Large menus & rebuilds

This section is again concerned with menus. In particular, how to create very large menus, how to 
completely change a menu (ie. a re-build), and add and remove items.

Menus can be created so that they can grow and shrink in accordance with what your application 
wants.

You should recall from the introduction section that when a menu is created a block of memory of a 
fixed size is reserved to put the data that the Wimp needs in. So for example:

menu%=FNwimp_createmenu(MyApp/Info/Quit,0)

will reserve a block of memory just big enough to hold the menu with only the two items specified.

But what happens if you want to add another item to the menu? This would create three items, so all 
the data for one item will be pushed into the next part of the memory. This could be holding the 
contents of variables that you are using, thus corrupting them, or even more likely you will crash
the  application, because you are trying to write to some memory addresses that dont actually exist 
(address exception errors are the result of this).

What is needed is a way of making sure the block of memory is big enough. This is where the last 
parameter to FNwimp_createmenu comes in. If it is less than or equal to the number of items 
specified in the string, then the block of memory will be just big enough to hold the items given.
If it is  bigger, then it is the maximum number of items that can be on that menu.

So if you used:

menu%=FNwimp_createmenu(MyApp/Info/Quit,20)

then you would create a menu the same as before, but you can have up to 18 further items added to it 
later on.

PROCwimp_putmenuitem and PROCwimp_removemenuitem add and remove items from  menus. Note: no check is
made to ensure that the menu is not bigger than the block of memory; you  will have to make sure
that the block is big enough.

PROCwimp_putmenuitem(menu%,item%,item$)
PROCwimp_removemenuitem(menu%,item%)

The parameters are mainly self explanatory. If item% in PROCwimp_putmenuitem is greater that  the
total number of existing items+1 then it will just be added onto the end. If item% is less than or 
equal to the number of existing items, the new item is inserted at item% and those below it are 
shuffled down. Removing items works similarly, with remaining items being shuffled up.

If you wanted to re-build or re-create a menu from scratch again, but still have the same handle as
the  last one, then you could call FNwimp_createmenu, which would get another chunk of memory and 
put the data needed into it. This means that the block of memory with the original menu in is still 
occupied and therefore wasted. If you do this repeatedly then more and more memory is taken up until 
your application runs out, crashing it.

A much better way is to use the wimp-function PROCwimp_recreatemenu, which updates the  data in the
block of memory containing the old menu.

PROCwimp_recreatemenu(menu%,menu$)

menu% is the handle of the menu to re-create. menu$ is a string to build the menu from, and is in 
the usual form, eg:

MyApp/Info/Quit

The number of items in the new menu shouldnt be greater than the specified maximum value when 
FNwimp_createmenu was called. For instance, the following would probably crash the  application,
because not enough memory has been allocated for all the items in the larger re-created  menu. e.g.:

menu%=FNwimp_createmenu(MyApp/Quit,1)
PROCwimp_recreatemenu(menu%,MyApp/Info/Quit)

When a menu is re-created, all the item attributes like dotted lines, greying out, and ticks are
removed  - so you would need to create these afresh, as required. 

If you want to change one or two menu items to reflect something in your application like: Save 
selection or Save depending in this case on whether anything was selected or not, then use 
PROCwimp_putmenutext instead, as all the attributes are then retained.

If, by recreating your menu an item is moved up or down, then its item% item number which is  passed
to user-function will change accordingly. (Remember this for the Quit item - the tip given  earlier
is very useful here.) The top item is always number 1.


However, FNwimp_createmenu and PROCwimp_recreatemenu have a major limitation: very  large menus
cannot be built - simply because the menu text needs to be contained within one Basic  statement,
which is limited to a little less than 255 characters.

DrWimp provides easy solutions to this: using modified versions of FNwimp_createmenu and 
PROCwimp_recreatemenu - and also using FNwimp_createmessagemenu.

The first solution is to put all the menu items into an array, then build the menu from the array.
This  lends itself very well to reading in items like font names, or data from support files for
your  application.

First of all you need to decide the maximum number of items in the menu. If you are creating a font 
menu, then you can use the SWI Font_ListFonts to find out the number of fonts. Anyway,  add one
onto the total size, and DIM an array.

The first element of an array (number 0) is the menu title. The last item must be the string END,
so  DrWimp knows how much of the array to use. 

 Note: END will not appear as a menu item; the element before it will be the last one.

Here is some example code:

DIM menu$(20)
menu$(0)=MyApp
menu$(1)=Info
menu$(2)=Quit
menu$(3)=END
barmenu%=FNwimp_createmenuarray(menu$(),20)
PROCwimp_attachsubmenu(barmenu%,1,info%)

which will create a two-item menu with the title MyApp and items Info and Quit.

FNwimp_createmenuarray is passed the name of the array (with empty brackets) and the  maximum number
of items. The last parameter is exactly the same as for FNwimp_createmenu, so  it could just as
easily be 0, which means that more items cant safely be added, but it makes more  sense to set it
as the size of the array.

Menus can be re-built using arrays as well. Instead of using PROCwimp_recreatemenu, use:

PROCwimp_recreatemenuarray(menu%,array$())

Menus created with a string can be recreated with an array, and vice-versa. Note: menus created with 
arrays can be manipulated using the same functions, such as PROCwimp_putmenuitem, 
PROCwimp_menuwrite, etc. The only difference is the way that the data to build the menu initially 
is stored (string or array).



It is also possible to create menus automatically from a message file - and you may need to refer
back  to Section 2.9 to recap on the message file structure in the following.

For example, say you had the following in a messages file:

BMenuT:Icnbar menu
BMenu1:Info
BMenu2:Quit

Then using the following, a basic iconbar menu could be created with the title Icnbar menu, and
two  items, the first being Info and the second being Quit:

barmenu%=FNwimp_createmessagemenu("BMenu","",0)

The first parameter is the tag (see Section 2.9) and is used to find the bits of the menu in the
messages  file. tag+T is the title, tag+1 is item one, tag+2 is item 2 and so on.

The second parameter is the menu title. In this case its an empty string so the one in the messages
file  is used. If, instead, we had put:

barmenu%=FNwimp_createmessagemenu("Bmenu",appname$,0)

then the menu title would be the string appname$, overriding the title in the messages file. In fact
if  you specify a menu title, then the tag in the messages file for the title doesn't have to be
included, and  you can just specify the items.

The final parameter is the maximum size of the menu, and allows the menu to be dynamic. It is 
exactly the same as the last parameter of FNwimp_createmenu.


Finally in this section, we come to PROCuser_overmenuarrow. This user-function is called  whenever
the mouse pointer passes over one of those little arrow-heads to the right of a menu item  when it
has a sub-menu (or window) attached to it. In its parameters it passes the handle of the sub-
menu/window about to be opened (in nextsubmenu%), the menu item number of the item with the 
arrow-head (parentmenuitem%) and the x/y values of the pointer position when moving over the  arrow
head. (Note that the first parameter has a RETURN in front of it. The use of this will be  explained
later in this section.)

This user-function paves the way to alter/rebuild etc. the about-to-be-opened sub-menu dynamically
if  you so wish - or even to display a totally different sub-menu/window.

For example, assuming the standard main menu with Info as its first item and the sub-menu (a 
window, here) handle of info% attached to it, you could make PROCuser_overmenuarrow look  like:

DEF PROCuser_overmenuarrow(RETURN nextsubmenu%,parentmenuitem%,x%,y%)
CASE nextsubmenu% OF
        WHEN info%
        CASE parentmenuitem% OF
                WHEN 1: PROCwimp_puticontext(nextsubmenu%,0,TIME$)
        ENDCASE
ENDCASE
ENDPROC

which would put the current time into icon number 1 of the info window each time you open it (but 
make sure icon 1 can accept indirected text up to 25 characters first!).

A more practical example might be:

CASE nextsubmenu% OF
        WHEN submenu1%
        CASE parentmenuitem% OF
                WHEN 2
                IF condition%=TRUE THEN
                        PROCwimp_menuenable(nextsubmenu%,3)
                        ELSE
                        PROCwimp_menudisable(nextsubmenu%,3)
                        ENDIF
        ENDCASE
ENDCASE

which would grey out Item 3 of the up-coming submenu if the current state of condition% is  FALSE
or enable the same item if condition% is TRUE - with condition% only being yested at the  time the
pointer goes over the arrowhead.

This user-function works for cascaded sub-menus in the same way i.e. if you have a fourth sub-menu 
to be opened from a third sub-menu then PROCuser_overmenuarrow will be called with the  fourth
submenu handle and the third sub-menus item number in the parameters.

Note that the x/y values made available in this user-function can often conveniently be passed
directly  through to other wimp-function calls that you might make here, for example to open a
window at a  certain place relative to the x/y values.

Finally, the purpose of the RETURN with the first parameter of this user-function. With this you
can, if  you so wish, completely change the sub-menu/window handle at this same over arrow-head
point  e.g. so that the user is presneted with one sub-menu/window in one set of circumstances and
another in  another set.

This is effected simply by reassigning the variable nextsubmenu% within the user-function. For 
example:

DEF PROCuser_overmenuarrow(RETURN nextsubmenu%,parentmenuitem%,x%,y%)
CASE nextsubmenu% OF
        WHEN info%
        IF registered%=FALSE THEN nextsubmenu%=unreginfo%
ENDCASE
ENDPROC

This would substitute the window unreginfo% for info% if the flag registered% is FALSE.  (The window
unreginfo% would, of course, need to be already loaded.)

As you can see, PROCuser_overmenuarrow really does allow you to manipulate your menus  very
dynamically - yet very simply.



16. Multitasking operation

This section is about multitasking, which can be used for many purposes e.g. raytracing, calculating 
numbers, loading data, file finding, etc. We are not going to show you how to write a raytracer,
etc. but  rather to show you how to make operations like these multitask easily.

One method of effecting multitasking is simply to set NULL% to TRUE at some point in your 
programme. As soon as this happens, the Wimp poll starts calling PROCuser_null every time that  it
receives a no-action needed Reason Code from the Wimp - which means  continuously. Every time  it
is called, you would need to do a small bit of work, each time remembering where you were up to  and
noting where youve reached. This can make very tangled code. The difficulty lies in storing  where
you got up to, and this can require a multitude of variables for just one operation.

A much easier method is to use PROCwimp_singlepoll. When called, it goes through the polling  loop
just once. Your operation will already be in some sort of loop, so all you have to do is call 
PROCwimp_singlepoll inside it. This very simple technique makes powerful multitasking  operations
very easy to achieve.

Change PROCuser_menuselection so it has lines like:

CASE menu% OF
WHEN barmenu% :
  CASE item% OF
  WHEN 1 : PROCchangeauthor
  ENDCASE
ENDCASE

And add the following function at the end of !RunImage:

DEF PROCchangeauthor
FOR L%=1 TO 200
  PROCwimp_singlepoll
  a$=
  FOR M%=1 TO 6
    a$+=CHR$(RND(26)+64)
  NEXT M%
  PROCwimp_puticontext(info%,3,a$)
NEXT L%
ENDPROC

Now run !MyApp and choose the first item on the iconbar menu. If you now look at the info window, 
the author field should be constantly changing with random letters. You can still use the desktop,
and  even quit the application.

Note: PROCwimp_singlepoll acts just like PROCwimp_poll. If one of your icons is clicked on,  then
PROCwimp_mouseclick is still called, and if your application received messages, then they  are acted
on, and so on.

Also note that there is another function that can be used for polling; PROCwimp_pollidle. If you 
remember, if NULL%=TRUE then every time that the Wimp is polled and no events have occurred, 
PROCuser_null will be called. If, instead, you used the following: PROCwimp_pollidle(30)

then PROCuser_null will be called only every 30 seconds. This reduces the load on the processor  and
is best used for things like clocks, etc, where you would only need to update the clock once a 
second or minute.

Note: if you have put a banner up and then used PROCwimp_pollidle with a time longer that the 
banner period, then the banner will stay up until the next PROCuser_null.

There is also the complement of PROCwimp_pollidle, PROCwimp_singlepollidle, which  is the same but
polls the Wimp only once instead of repeatedly.



17. Bars

When you format a floppy disc a horizontal bar increases in size to show the amount of the disc that 
has been formatted so far. Similarly, when you look at the free space on a floppy or hard drive you 
have several bars to show you how much space has been used up, how much is free, and what there is 
in total. Again, when you open the task display you are shown lots of bars that depict the amount of 
memory something is using up.

Using DrWimp it is simple to control bars like those yourself. They can make information look much 
more attractive than numbers.

Bars are only long, thin icons filled with a colour. DrWimp allows the length (or height) of bars to
be  changed. This means, for instance, that they can be changed continuously or only just before a
window  containing them is opened.

Make a fresh copy of !MyApp. From the Tutorial folder, drag the Template5 file into the !MyApp 
directory, and rename it as Templates. Add the following lines to PROCuser_initialise in 
!RunImage:

main%=FNwimp_loadwindow(<MyApp$Dir>.Templates,main,0)
bar%=FNwimp_iconbar(!MyApp,,0,1)
barmenu%=FNwimp_createmenu(MyApp/Quit,0)

and in PROCuser_mouseclick:

IF window%=bar% THEN PROCwimp_openwindow(main%,1,-1)

and in FNuser_menu:

Return%=0
IF window%=bar% THEN Return%=barmenu%
=Return%

and in PROCuser_menuselection:

IF menu%=barmenu% AND item%=1 THEN PROCwimp_quit(0)


If you now double-click on !MyApp you should get an icon on the iconbar with a menu with a Quit 
item. Clicking on the icon should produce a small window with a red bar in it. What we are going to 
do is set the bar to a random length when it is clicked on.

First we need to know what the maximum length is, so load the templates into !TemplEd by dropping 
the file onto !TemplEds iconbar icon.

Open the main window by double-clicking on it in the window at the top left. Expand the icon info 
window at the top right to full size and move the pointer over the bar.

The icon info window gives the dimensions of 340x36, so the max length is 340. Of course we could 
extend the icon to whatever size we want using !TemplEd, and then using that length.

Take a look at all the details of the bar icon by double-clicking on it. This is how you should set
up  any icons you want to use as bars. Obviously you can change the colour and turn the border on,
etc.

Returning to !RunImage, add the following line to PROCuser_mouseclick:

IF window%=main% THEN PROCchangelength

Now add the following function to the end of !RunImage:

DEF PROCchangelength
len%=RND(340)
PROCwimp_bar(main%,1,len%,0)
ENDPROC

Re-load !MyApp, and click on the bar or frame icon behind it.

It is quite easy to specify the length as a percentage. Alter PROCchangelength to:

DEF PROCchangelength
len%=RND(100)
len=(340/100)*len% :REM** To factor the bar length correctly. **
PROCwimp_bar(main%,1,len,0)
ENDPROC

As you can see, len% is a percentage chosen at random.

And just to finish off, alter PROCchangelength to:

DEF PROCchangelength
pcent%=0
REPEAT
  nlen=(340/100)*pcent%
  PROCwimp_bar(main%,1,nlen,0)
  PROCwimp_singlepoll
  pcent%+=2
UNTIL pcent%>100
ENDPROC

You should be able to see that it is now the basis for a multitasking operation with the percentage
done  depicted by the bar. Put the operation inside the loop, and each time round the loop calculate
the  percentage done instead of incrementing it as we have done.

You can change the bar to look like however you want it, but we would advise against adding any
text,  sprites, or indirected text.

One thing you might like to do is add a border around the bar by clicking on the Border icon in
the  relevant !TemplEd window. However, if the bar is going to be changing in size rapidly then the
part of  the border at the right edge will flicker a lot as that part of the screen is constantly
redrawn.

If you want the bar to be a vertical one, i.e. it resizes vertically instead of horizontally, then
set the  fourth parameter of PROCwimp_bar to 1 instead of 0.

(See the end of the next section for some general comments on the practical use of bars/sliders.)



18. Sliders

Sliders can be very useful. You see them probably most in colour selection windows, where you can 
use them to drag amounts of red, green and blue.

Sliders consist of three icons, and must be constructed in a certain way in order to work properly:



The slider back icon goes completely under the slider icon, and defines the area over which the
slider  can be dragged.

The slider and slider back icons must both have a button type of Click/Drag, be filled and have no 
borders. They however can be any thickness, length or colour you like.

Look at how the sliders are constructed in the supplied templates file if it is still not quite
clear.

Copy the file Template6 from the Tutorials folder into !MyApp and rename to Templates. After the
line where the main window is loaded in add:

slide%=FNwimp_loadwindow("<MyApp$Dir>.Templates","slide",0)

Alter the window%=bar% part in PROCuser_mouseclick so that is is like:

IF window%=bar% THEN PROCwimp_openwindow(slide%,1,-1)

Run !MyApp and you will see that the slider window that appears has two sliders in it. Currently
they  do nothing.

Just like FNuser_savefiletype makes save windows work as soon as some value is returned for  them,
sliders work as soon as you return relevant values from two user-functions.

FNuser_sliderback is used to tell the Wimp which slider back icon is linked with which slider  icon.
For the top slider (loading the templates into !TemplEd will show this), the slider is icon number 
2, and the slider back icon is icon number 1. So add the following line to FNuser_sliderback:

Return% = -1 :REM** Note this empty value, as icons can have the number 0. **
IF window%=slide% AND icon%=2 THEN Return%=1
=Return%

To complete the pairing, FNuser_slider must also be used to return the icon number of the slider 
icon, when given the slider back icon number. So, add the following line to FNuser_slider:

Return% = -1
IF window%=slide% AND icon%=1 THEN Return%=2
=Return%

Hopefully that should be clear, and running !MyApp will  now enable you to click on the top slider
or  the slider back to make it jump to various positions. You can also drag the slider left and
right.

A slider is no good unless you can get a value for it. When a slider is moved or dragged, 
PROCuser_slidervalue is called, and the percentage of the slider concerned (and its direction, 
hor/vert) is passed. So add the following lines to it:

IF window%=slide% AND icon%=2 THEN
  PROCwimp_puticontext(slide%,3,STR$(pcent%))
ENDIF

STR$(pcent%) converts the percentage to a string, suitable for passing to  PROCwimp_puticontext.
Icon number 2 is the slider icon. Run the application now and you will  see the percentage displayed
in the box on the right.

Add the following line to FNuser_sliderback:

IF window%=slide% AND icon%=6 THEN Return%=5

and this line to FNuser_slider:

IF window%=slide% AND icon%=5 THEN Return%=6

and finally these lines to PROCuser_slidervalue:

IF window%=slide% AND icon%=6 THEN
  PROCwimp_puticontext(slide%,7,STR$pcent%)
ENDIF

The bottom slider should now work, and you can see how many sliders can be used in many windows. The
percentage can be scaled up or down so different ranges can be used, e.g. 0-255.

The percentage of a slider can be read using FNwimp_getsliderpcent and the percentage of a  slider
can be set using PROCwimp_putsliderpcent. Try these out to see their effect.

Vertical sliders can also be made. If the slider is made higher than it is wide, then DrWimp will 
automatically assume its a vertical slider.

The example application !Sliders shows a typical application with both horizontal and vertical
sliders.  In addition it introduces nudgers/bump icons which are often used to complement
sliders/bars by  providing a means to fine-tune values set with a slider/bar. The !Sliders listing
will show that  bumpicons/nudgers are exceedingly easy to implement using standard Basic
statements.

!Sliders will also demonstrate some of the practical issues in using sliders/bars - which are
features of  all sliders/bars rather than being unique to Dr Wimp. For instance, it is often not
possible to use the  mouse pointer accurately enough to set every value in the slider/bar range
(hence the need for  nudgers/bump icons).



19. Loading & Saving Drawfiles

We are not going to add drawfiles to !MyApp here as the example in the Examples folder shows how  it
is all done. Instead we will cover some points that are worth mentioning.

Firstly, drawfiles are handled in the same way as sprites (see Section 2.12). Recall that a handle
is  chosen to point to the start of a memory block. Drawfiles are all loaded in sequence into the
same  block of memory and we end up with a discrete handle/pointer for each drawfile in the block.

As was said before, the sequence is simple but must be adhered to strictly.

For example, lets assume that we have three drawfiles already waiting within the !MyApp directory. 
If we want to load them for use in our application we would use the following code in 
PROCuser_initialise:

PROCwimp_initdfiles
path1$="<MyApp$Dir>.Drawfile1"
path2$="<MyApp$Dir>.Drawfile2"
path3$="<MyApp$Dir>.Drawfile3"
size%=0
size%+=FNwimp_measurefile(path1$)
size%+=FNwimp_measurefile(path2$)
size%+=FNwimp_measurefile(path3$)
DIM drawfiles% size%
DIMdfilehan%(3)
dfilehan%(1)=drawfiles%
dfilehan%(2)=FNwimp_loaddfile(path1$,dfilehan%(1))
dfilehan%(3)=FNwimp_loaddfile(path2$,dfilehan%(2))
d%=FNwimp_loaddfile(path3$,dfilehan%(3))

So you end up with dfilehan%(1) as the handle for the first drawfile, dfilehan%(2) as the  handle
for the second, etc. The unused dummy handle is d%. The only difference from our sprite  example is
that we have used an array to hold the handles.

Never try to work out the sizes of the drawfiles using any other method but  FNwimp_measurefile,
otherwise you may run into trouble. To load in more drawfiles, include  them in the size totalling
part, then DIM the handle array to the right size, then expand the list of  FNwimp_loaddfile calls
to the required number.

As a final example, how to load in a single drawfile:

PROCwimp_initdfiles
path1$="<MyApp$Dir>.Drawfile1"
size%=0
size%+=FNwimp_measurefile(path1$)
DIM drawfiles% size%
DIM dfilehan%(1)
dfilehan%(1)=drawfiles%
d%=FNwimp_loaddfile(path1$,dfilehan%(1))

You could in this case remove the dfilehan% array and just have drawfiles% as the handle, but  that
is up to you to choose which you prefer.

Drawfiles can easily be saved using PROCwimp_savedfile. Eg. to save the first drawfile to a path 
stored in path$:

PROCwimp_savedfile(path$,dfilehan%(1))


20. Rendering Drawfiles & Sprites

Drawfiles and sprites can be rendered (drawn!) straight onto the screen at a specified position or into a 
window similarly. The latter is usually much more useful, but is only a derivative of the former. In 
both cases, the drawfile/spritefile must have previously been loaded in one of the previously described 
ways - or, from Version 3.56 onwards, sprites in the Wimp sprite pool can also be rendered directly.

The wimp-functions provided for rendering drawfiles and sprite files allow scaling in the x and/or y 
direction, but any other required translation e.g rotation/shearing/reversal etc. of objects needs to be 
done previously in the source sprite/drawfile.

The following notes treat drawfiles first and then sprites.


Within drawfiles, all the standard types of object - except one - are duly rendered (i.e. paths, text, 
sprites, transformed text, transformed sprites). The exception is the special drawfile text areas - 
including text column objects. These are very complex and are not rendered. Fortunately, they are 
rarely used.

PROCwimp_render renders drawfiles directly onto the screen. The coordinates of the bottom left 
corner are supplied, and two pairs of coordinates to define a clipping rectangle. Any objects lying 
totally outside the clipping rectangle are not rendered.

It is complemented by PROCwimp_renderwindow which renders a drawfile inside a window, and 
is called in PROCuser_redraw. For example, with:

IF window%=main% THEN
  PROCwimp_renderwindow(main%,dfilehan%(1),50,-250,minx%,miny%,
maxx%,maxy%,xscale,yscale,origin%)
ENDIF
which specifies that the bottom left corner of the rendering of dfilehan%(1) shall be at the point 
50, -250 (OS work units) in the window main%.

Note that in order for PROCuser_redraw to be called, a window must have its 
auto-redraw flag unset in the template editor.

xscale and yscale are the scaling factors. They are real numeric variables and only positive scale 
values can be used (i.e values greater than 0). Values less than 1 will reduce the displayed size of the 
drawfile and values greater than 1 will increase it. That is, the value 1 represents no change i.e. the 
rendered drawing will be at the same size as the source drawing. 

origin% is a flag to activate an optional feature which can be very useful. The natural origin of all 
drawfiles is the bottom left corner of the !Draw page. However, very often, a drawfile is constructed of 
objects drawn higher up on the page - with, say, some empty space below and/or to the left of a 
rectangular bounding box which would just surround all the objects, as below:



Such a drawfile can be rendered in one of two ways: if origin% is set to 0 then the whole drawfile 
page will be rendered naturally i.e. the bottom left corner of the drawfile page (A) will be located at 
the specified x/y position. However, if origin% is set to 1 then the drawfile will be rendered with the 
bottom left corner of its overall bounding box (B) located at the specified x/y position - i.e. exactly as 
if the overall bounding box of the objects was at the bottom left corner of the drawfile page.

This latter option makes it much easier to place drawfile objects exactly where you want them without 
needing to worry about any unwanted offsets which may occur when using natural rendering. This 
option also correctly takes into account any scaling required by xscale and yscale.

FNwimp_getdfilesize returns the width and height of a drawfile so a window could, for 
instance, be resized to the size of the drawfile and then displayed in it.



Rendering sprites in Dr Wimp is a very similar process to rendering drawfiles, although sprites do not 
need an equivalent to the above origin% flag.

PROCwimp_rendersprite is the sprite equivalent to PROCwimp_render and works in exactly 
the same way, but instead of having a drawfile handle, there is the sprite name and the user sprite area 
handle which contains that sprite.

The wimp-function for rendering a sprite in a window is PROCwimp_renderwindowsprite, and 
for finding the dimensions of a sprite is FNwimp_getspritesize.

The following is an example for rendering a sprite (assuming it has already been loaded into a user 
sprite area whose handle is sprite%):

IF window%=main% THEN
PROCwimp_renderwindowsprite(main%,"test",sprite%,50,-250,minx%,miny%,maxx%,maxy%,xscale,yscale)
ENDIF


From Version 3.56, a further option is available for rendering sprites which are in the Wimps sprite 
pool. This Wimp pool is intended for sprites which are available for common Wimp operations. Thus, 
all the icons for a windows furniture will be in this pool, as well as sprites intended for standard file 
icons e.g. Basic/Obey/Text/Draw/Paint/Help/Printers etc. files. Pointer shapes are also found here. (A 
look at the sprite files inside Resources:$.Resources.Wimp will show the range of sprites 
typically in the Wimp sprite pool.)

You will also be aware that it is normal for all applications to add some items to this pool, via an 
*Iconsprites call in their !Run and/or !Boot file. For instance, the unique sprite(s) for an 
applications filer icon and iconbar icon would normally be loaded into the Wimp sprite pool in this 
way.

If a sprite is in this pool then a pair of wimp-functions allows any of them to be rendered directly 
(including scaling, if required) without the need to load them into a user sprite area. These are 
PROCwimp_renderpoolsprite and PROCwimp_renderwindowpoolsprite. Their 
parameters are identical with their counterparts described above, except that no parameter for a sprite 
area handle is needed.

(N.B. Although the Wimp sprite pool method offers the opportunity to treat any sprite this way simply 
by including it in an *Iconsprites call, it does have the major disadvantage of taking up memory 
space even after the application has been quit. In contrast, the user sprite area method is to be much 
preferred in this respect - see Section 2.12. So it is best to regard PROCwimp_renderpoolsprite 
and PROCwimp_renderwindowpoolsprite solely as facilities to gain direct access to sprites 
whose proper location is the wimp sprite pool, without having to copy them into a user sprite area 
first.)


In the Examples folder there is a full application demonstrating these rendering operations.


The most common practical problems with rendering graphics (and text) concern getting the 
coordinate conversions right - always remembering that the actual Wimp plotting coordinates will 
need to be in screen coordinates, whereas you will often need to do all your work in work area 
(window) coordinates. DrWimp provides all the necessary conversion functions. Dont forget that, in 
windows, all visible y work area coordintes will be negative. By and large, if your rendering action 
appears to produce nothing visible yet no error messages appear, then a common problem is that the 
rendering is actually off-screen or outside the window (with a drawfile this could also simply be the 
result of having the flag origin% set wrongly). (The charity book Dr Wimps Surgery takes you 
through the rendering and coordinate conversion processes step by step.)

Finally, you may (rarely) run across a sprite which does not render in the correct colours. If this 
happens, try using the alternative sprite rendering method (i.e. if it is in the Wimp sprite pool and 
PROCwimp_renderwindowpoolsprite gives wrong colours, copy it to a user sprite area and 
use PROCwimp_renderwindowsprite instead) or drag the sprite to a drawfile and render the 
drawfile instead.



21. Validation Strings

Each icon has a validation string. This can be empty or contain some commands which are separated 
by semicolons. The validation string for an icon is normally set in a template editor when editing
the  icon, and for those with the RISC OS 3 Programmers Reference Manuals all the options can be
found  on page 3-102.

The validation string is an indirected text string (see next section) whose memory location is set
up  as part of the icon definition.

A common command is Rn, where n is a number from 0 to 7, which specifies the border type for the 
icon. For example, R6 is the default action type border and R7 is a writable icon type border. R0 is 
equivalent to not using the R-command.

If the icon can be pressed in then the slab in colour can be set. If you create a default action
button  in !TemplEd you will see that the validation string is R6,3. Try changing the 3 to 7 or 11.

In Section 2.12 we saw that another very common command is Pspritename, where  spritename is the
name of a sprite for the pointer when the pointer is over that icon.

If you have lots of writable icons in a window then you can make it so that the caret can be moved 
between them with the Up and Down arrow keys, Tab and Return. If you put Ktar in the validation 
string of all your writable icons then they can all be navigated in that way. t - Tab, a - Up/Down
Arrow  keys, r - Return. You can use any combination you like.

The caret will move in order of icon number so if you have writable icons numbered 3,11,7,8,2 then
it  will move in the order: 2,3,7,8,11 for the Down arrow, Tab or Return and 11,8,7,3,2 for the Up
arrow.  So make sure that if you are going to use this then your writable icons are numbered in such
a way that  the caret will move in a predictable manner.

As mentioned, more than one validation string command can be used for each icon if they are 
separated by semicolons. So for a typical writable icon you may have: R7;Pptr_write;Ktar

(A comprehensive explanation of all validation string commands is contained in Dr Wimps Surgery 
- the charity book mentioned at the start of this Manual.)



22. Indirection

Throughout this manual, you will have seen many references to indirected icons or indirected
text.  Here is a brief description of what it means, and why it is important to using the Wimp. (Dr
Wimp  actually removes all the complications of handling indirected or non-indirected features, but
it is  nonetheless better to have an appreciation of this topic.)

Each icon in the desktop is defined by a small block of memory. This block is of a fixed size and 
contains a complete description of the icon so that the Wimp can draw it.

This block contains the dimensions, several flags containing information such as whether it is a
sprite,  text, sprite and text, filled, has a border, etc and some data on what it contains, such as
actual sprite  name or text. Most of the flags you can toggle between set and unset using a template
editor, such as  !TemplEd.

The total size of the icon block is 32 bytes. 12 of these are used for holding the data concerning
the  text and/or sprite used in the icon. You can specify a text-only icon, a sprite-only icon or a
text-plus- sprite icon. You can also specify whether the text or icon name is to be indirected or
non-indirected.

If you choose non-indirected it means that the text (or icon name) is held in the icons data
block  directly - and thus cannot be changed and is subject to a rather small maximum size (11
characters  plus a terminator).

If you choose indirected it means that the icons data block holds the value of the maximum 
allowable length of the text and a pointer (memory location) to where the text is stored. Thus the
text  in the icon can easily be changed by changing the text in the memory location where it is
stored and it  is not subject to the 11+1 character limit.

Therefore, indirection - which is a general concept - essentially means that the text ( or sprite
name)  is held somewhere else which is located by its memory pointer. Indirection can apply to many
other  circumstances e.g. window titles, menu title/text.

If you use an indirected text-plus-sprite icon, the text is indirected as just described but the
indirected  sprite name is then held in the validation string - under the S-command (see earlier) -
which itself is  indirected memory space.

Once an icon has been created (ie. your program has loaded in the window containing the icon) then 
you can only change certain things in the icon block. You cannot change the contents of the data 
section. However, if the icon is indirected then you can change the text or sprite name because it
is not  actually held in the icon block but in another block of memory elsewhere.

If you make an icon indirected with an indirected size of, say, 16 and then use 
PROCwimp_puticontext to put in a string greater than 15 characters long (15 plus terminator  equals
16), strange things may happen. The most common is that if the icon has a 3D border then it is 
lost. The more you go over the limit, the messier things get - so dont!

Once you have decided whether or not to use indirection in icons and window titles when preparing 
your window templates, Dr Wimp removes all the complications of handling the consequences of the 
choice.



23. Text Handling

You should, by now, be able to see how to plot drawfiles and sprites in a window (using 
PROCuser_redraw). With DrWimp it is also possible to plot text in a variety of ways directly onto  a
window or the screen. Any outline font can be used at any size and in any colour.

Some of the functions require the name of the font to be provided. The font names always have to be 
what is called period separated. For example:

"Trinity.Medium"
"Homerton.Bold.Oblique"
"Corpus.Medium.Oblique"

i.e. there are periods (full stops) between each part - conforming with file naming, in fact.

PROCwimp_plottext is the most basic function provided, and simply plots a string of text onto the 
screen at the required position. It has rather a lot of parameters but they are straightforward i.e.
the  text, the name of the font you want to use, the point size and foreground and background
colours and  the screen OS units position where you want the text to start.

PROCwimp_plotwindowtext does the same but plots the text in a window, so it needs the  window handle
and the position is given in work area OS units. (As plotting text in a window this way  is simply
another form of graphics plotting, you would use this inside PROCuser_redraw, as with 
PROCwimp_renderwindow and PROCwimp_renderwindowsprite.)

Fonts can have handles, just like windows, drawfiles, sprites, etc. In fact, the Wimp needs font
handles  and uses them in a way more akin to file opening/closing. e.g. a font handle is needed
before text  plotting can take place and the font needs to be closed after its last use.

Whenever PROCwimp_plottext or PROCwimp_plotwindowtext is called, a handle for the  font is found
automatically behind-the-scenes before the string is plotted. If you are plotting many  lines of
text, all this handle finding can take a lot of time - so DrWimp provides a way of overcoming  this
by providing a wimp-function to find the handles for you, plus a set of slightly different wimp-
functions to plot the text with them.

FNwimp_getfont returns a font handle when you tell it the font you require and the point size. You 
would thus normally get all the handles you require when your application loads, in 
PROCuser_initialise. (0 is returned if the font could not be found so you would have to take  into
account of this and perhaps find an alternative and warn the user.)

For example:

trinity12% = FNwimp_getfont("Trinity.Medium",12)

To plot text, PROCwimp_plottexth and PROCwimp_plotwindowtexth are used. Note the  h on the end of
the function name to denote that those functions accept font handles instead of fonts  names and
sizes.

In PROCuser_redraw the following is a typical example:

IF window%=main% THEN
PROCwimp_plotwindowtexth(main%,"Test",trinity12%,50,50,0,0,0,255,255,255,minx%,miny%,maxx%,maxy%)
ENDIF

Note the foreground and background colours. 0,0,0 sets the foreground to black, and  255,255,255
sets the background to white.

Finally, when you have finished with a font, you call PROCwimp_losefont. For example:

PROCwimp_losefont(trinity12%)

This would normally be called when your application is quitting, i.e. in FNuser_quit.

Not just simple strings of text can be plotted. Strings of control code sequences can be inserted
into the  string to turn underlining on and off, change the font, or change the font colour. DrWimp
provides  functions to produce these control strings. For example:

t$="Cat "+FNwimp_fontunderline(1)+"dog"+FNwimp_fontunderline(0)+" hen."

when plotted would result in the word dog being underlined. Note the positioning of the spaces 
between the three words so they don't get underlined as well.

An example of turning the text red:

t$="Cat "+FNwimp_fontcolour(255,0,0)+"dog."

would make the word dog. turn red. The text can be turned black again afterwards with 0,0,0.

And for changing the font (assuming homerton20% is a font handle already found):

t$="Cat "+FNwimp_fontchangeh(homerton20%)+"dog."

would make the word dog. appear in the font whose handle is homerton20%.

Note that there isn't an equivalent FNwimp_fontchange (no h) as the control sequence only  works
with font handles.

Any combination of these can be used to produce the effect you want. Note that if you plot a string 
and the end of it is in red for example, then the next line you plot will be in black again. There
is no  need to change the colour back to black as all effects such as colours, underlining and
changing font  only apply for that line only.

There are two functions for finding the width and height of a string, as if it were plotted on the
screen.  They are FNwimp_gettextsize and FNwimp_gettextsizeh, with the latter using font  handles
instead of font names and sizes. These wimp-functions are very useful for positioning text 
accurately - particularly for vertical alignment.

Finally, there are two functions which also plot text, both on the screen and in windows, but they
don't  always plot with outline fonts. The functions are PROCwimp_deskplottext and 
PROCwimp_deskplotwindowtext and they plot using the current desktop font - either straight  to the
screen or to a window, respectively.

On pre-RISC OS 3.5 machines, only the system font can be used for the desktop font,  so that is
what will be used with the above wimp-functions. However, on RISC OS 3.5+  machines the desktop
font can be configured to be an outline font or the system font.  Therefore the above
wimp-functions will then use whatever the desktop font is  configured to be.

These two functions are useful for matching the fonts displayed directly onto the window with that 
used in icons. You supply the string to plot, the position and the foreground and background
colours.  There is an extra parameter which allows you to choose whether to plot with the left side
of the text at  the x-coordinate, or plot with the text centred on the x-coordinate. 



24. Printing

Dr Wimp provides comprehensive facilities for you to print via the RiscOS printer drivers. but you 
need to have a fairly good grasp of how to use DrWimp. Also, as there a quite a bit to set up before
the  printing actually starts and nothing can be tested until its mostly all done, it is not
practicable to have a  step-by-step tutorial for this section. However there are some example
applications in the Examples  folder ( .... and Dr Wimps Surgerycovers it in detail!)

As you have seen, it is possible to plot text, sprites and drawfiles in windows by doing the
relevant  work in PROCuser_redraw. But what if you want to print it out? For a start the position
origins are  different: the work area has its origin at the top left of a window, making all visible
y coordinates  negative. Conversely, for hard copy printing the origin is traditionally at the
bottom left corner of the  paper. Plus it seems that if you want to print out what you have
described in PROCuser_redraw,  you will have to duplicate it all again. Then there may be the
problem of fitting lots of pages onto one  page by reducing them in size and rotation, etc .......

As usual, Dr Wimp provides easy solutions to these problems.

There are two methods you can use to print out and which you choose depends on the application. If 
you want to print out what is being shown in a window which has all been written/drawn in 
PROCuser_redraw, then you use what we will call the redraw method (or wysiwyg). If on the  other
hand you want to print out something that is independent of the display, then you do all the work 
in a user-function, PROCuser_print. We will call this the user method.

Either way, DrWimp makes it relatively easy to print out documents. The main workload involved is 
coordinate conversion between screen/work area and paper. This is fairly straightforward, with the 
wimp-functions provided, but needs a methodical approach..

DrWimp also provides facilities to find out about the paper size, the  printer driver and a means
for the  application to tell the user what is going on and giving them the option to cancel the
printing.

The first thing your application needs to do is have some sort of print choice window where the user 
can specify the range of pages to print, how many to fit onto a page and the number of copies to
print.  As a bare minimum, a simple Print button will suffice.

Another early check needed is to ascertain that a printer driver is loaded, otherwise your
application  will produce errors and probably quit. For example, using:

loaded%=FNwimp_pdriverpresent

will result in loaded% being equal 1 if a printer driver is loaded, and 0 if one isn't.

This isnt the end of printer driver checking though. Users can load, change and quit printer
drivers at  any time whilst your application is running. So it needs to be checked continually and
Dr Wimp has a  user-function to do just this. It is PROCuser_printerchange and it is called any time
the status  of the printer driver changes. Thus you can fill this user-function with routines to
react as you wish  when it is called. For instance, you could check if a driver is still loaded and
enable/disable icons  accordingly e.g. to prevent a Print button from being pressed.

A common practice is to put the name of the current printer in the titlebar of the window or 
somewhere in the window. So for example you could use:

loaded%=FNwimp_pdriverpresent
IF loaded%=1 THEN
  printername$=FNwimp_getpdrivername
  PROCwimp_putwindowtitle(print%,printername$)
ELSE
  PROCwimp_putwindowtitle(print%,"No printer loaded")
ENDIF

with print% being the handle of your print window. Its easy to see that in the IF..ELSE..ENDIF 
structure you can enable and disable icons in the print window depending on whether the printer
driver  was loaded or not.

If you wish you can also get information about the paper size and the printer borders (which you
can't  print in). With this you could, for example, draw grey and white rectangles to depict the
page and its  borders. But be careful not to try and get any information about the page unless a
printer driver is  loaded!

As a very brief example, here is a sample piece of code that could go in PROCuser_redraw for a 
print window (assuming its auto redraw flag is not set):

IF window%=print% THEN
  IF FNwimp_pdriverpresent THEN
    w%=FNwimp_getpapersize(0,0)
    h%=FNwimp_getpapersize(1,0)
    IF h%>=w% THEN scale=h%/120
    IF w%>h% THEN scale=w%/120
    w%=w%/scale
    h%=h%/scale
    x%=FNwimp_worktoscreen(print%,316,0)
    y%=FNwimp_worktoscreen(print%,-256,1)
    PROCwimp_setforegroundcolour(160,160,160)
    RECTANGLE FILL x%,y%,w%,h%
    lm%=FNwimp_getpapersize(0,1)/scale
    r%=FNwimp_getpapersize(0,3)/scale
    bm%=FNwimp_getpapersize(1,1)/scale
    t%=FNwimp_getpapersize(1,3)/scale
    PROCwimp_setforegroundcolour(255,255,255)
    RECTANGLE FILL x%+lm%,y%+bm%,r%-lm%,t%-bm%
  ENDIF
ENDIF

which will draw in the window a small depiction of the paper in the window with borders.

The key lines are the calls to FNwimp_worktoscreen which, as its name says, takes a work area 
coordinate and translates it into a screen coordinate. (It may be slow due to it having to find out
if a  printer driver is loaded every time a bit of the window needs redrawing, although you could
optimise  it to take into account the redraw clipping rectangle passed to PROCuser_redraw.)

Currently DrWimp supports printing ranges of pages, multiple copies and fitting one, two or four A4 
pages onto a single physical A4 page, so these are the options you can provide in your print window. 
For an example see the template file Print in the tutorials folder.

As was said before, at any time the user could change the current printer, and then 
PROCuser_printerchange will be called automatically. When it is, you would check to see if  the
printer driver is still loaded, and update all your page measurements, what icons to enable and 
disable in the print window etc. Basically do all your checks again just as if the print window was 
being opened for the first time.

If you are printing with outline fonts, which is probably very likely, then there is one more
preparatory  consideration to take into account. Postscript printers either have fonts with
different names or only a  small selection of fonts, so some printer drivers, particularly
postscript ones, may require all fonts that  are going to be used, to be declared first. As we don't
know what printer the user is going to use, or if  they require fonts to be declared, we must always
declare them. This is done in the user-function  PROCuser_declarefonts and Dr Wimp provides all the
necessary functions to make it simple.

Similarly, if you going to print any drawfiles that contain fonts, then the fonts in them also need
to be  declared - again via a provided wimp-function.

In the user-function PROCuser_declarefonts you must call, for each font,  PROCwimp_declarefont if
you want to supply the font name, or PROCwimp_declarefonth  if you want to give the font handle
instead. For drawfiles with fonts in them you call  PROCwimp_declaredfilefonts, giving the handle of
the drawfile, for each drawfile. For  example:

DEF PROCuser_declarefonts
  PROCwimp_declarefont("Trinity.Medium")
  PROCwimp_declarefonth(homerton18%)
  PROCwimp_declaredfilefonts(dfilehan%(1))
ENDPROC

See the section on text handling (Section 2.23) for more information on font handles and period 
separated font names, and see the section on loading drawfiles (Section 2.19) for more information
on  drawfile handles.

Once you have everything set up you are ready to print and one wimp-function initiates it.

PROCwimp_print(user%,window%,fpage%,lpage%,perpage%,copies%,orient%)

Setting user% to 1 prints using the user method, and setting it to 0 prints using the redraw method. 
Both of these will be discussed in more detail later.

If using the redraw method then window% is the handle of the window to redraw. In other words the 
window whose contents you want to print out. window% is ignored if printing with the user method - 
but a value must be present, of course.

fpage% and lpage% are the page numbers of the first page to print and the last page, respectively. 
These are inclusive, and it doesnt really matter to DrWimp what they are as long as lpage% is equal 
to or larger than fpage%. The numbers you specify for the range of pages are arbitrary as far as 
DrWimp is concerned, as the whole range of page numbers will be returned to you one by one as you 
are requested to print each page. perpage% can currently be either 1, 2, or 4. If you set it to 1
then each page will fit on a physical A4  page. If you specify 2 then two A4 pages will be scaled to
about 70%, rotated through 90 degrees, and  placed side by side on a physical A4 page. If you
specify 4 then each page will be scaled to 50% and  four pages will be printed on a single physical
A4 page. All this is done automatically and the printing  as far as you are concerned is exactly the
same, just that the actual output is affected.

copies% is the number of copies to print. For example if you want to print from page 1 to 4, with 
two copies, then eight pages will be printing, two lots of four. The number of physical pages
printed  depends on perpage% though.

orient% specifies the orientation of the paper. If orient%=0 then the paper is portrait, but if you 
set orient% to 1 then the paper will be treated as landscape. The orientation argument is also 
required when converting to and from paper coordinates, as the orientation of the paper affects
where  the work area and screen coordinates translate to on the paper.

During printing you may wish to keep the user informed of the progress of the printing and give them 
the option to cancel. This is easily achieved as FNuser_printing is repeatedly called. From it you 
can read the current copy being printed, the current page number, the total number of pages that are 
being printed, and the current page being printed (from one to the total number).

From the total number of pages and the current page being printed, you could calculate the
percentage  of pages already printed and display a progress bar using PROCwimp_bar. You could also
display  the current copy and current page out of interest.

Finally, in the progress window you could add a cancel button, and when it is clicked on you set a 
variable to indicate that the user wishes to cancel printing. Then, when PROCuser_printing is  next
called, you look at the variable and return a 1 if the printing is to be cancelled. Otherwise you 
return a 0.

Here is an example of the sort of thing you might put into the user-function:

DEF FNuser_printing(copy%,page%,totpages%,pagepos%)
PROCwimp_puticontext(prog%,0,Printing page+STR$page%+ (copy +STR$copy%+))
PROCwimp_bar(prog%,2,(pagepos%/totpages%)*466,0)
=cancel%

In the example, prog% is the handle to the progress window, the progress bar is icon number 2, 
which is 466 OS units long, and icon 0 is just a text icon to display information.

cancel% is set to 0 just before PROCwimp_print was called, and in PROCuser_mouseclick  there would
be a line like the following:

IF window%=prog% AND icon%=4 THEN cancel%=1

where icon 4 is the cancel button. FNuser_printing can then simply return cancel% to indicate  if
printing is to be cancelled or not.

Here are a couple of further examples to help you understand the difference between page% and 
pagepos%:

Say the user wanted to print pages 2 to 8, one copy. Then as printing progresses copy% will  stay at
one, page% will start at 2 and increase to 8, totpages% will stay at 7  (printing pages 2 to 8
inclusive), and pagepos% will start at 1 and increase to 7  (totpages%).

If the user was printing pages 4 to 6, 2 copies, then copy% will start at 1 and increase to 2, 
page% will start at 4 and increase to 6, totpages% will stay at 3, and  pagepos% will start at 1 and
increase to 3 (totpages%).

Now, at last, we come to the actual printing: the actual construction of the pages. First, using the 
redraw method.

When PROCuser_redraw is called and printing is occurring, the variable printing% will be  TRUE, and
page% will contain the page number to print. Lets take a simple example of plotting one  line of
text in Trinity.Medium at 12pt. We will assume a handle for the font has already been  obtained and
is in trinity12%. The window we are plotting in has the handle main% (ie. the  window handle passed
to PROCwimp_print was main%), and the text is placed at the work area  coordinates 50,-100.

Firstly, looking at just the screen display needs:

DEF PROCuser_redraw(window%,minx%,miny%,maxx%,maxy%,printing%,page%)
IF window%=main% THEN
  x%=50:y%=-100
  string$="DrWimp printing test."
  PROCwimp_plotwindowtexth(main%,string$,trinity12%,x%,y%,0,0,0,255,255,255,minx%,miny%,maxx%,maxy%)
ENDIF
ENDPROC

Now take a look at how it would be modified to allow these same contents of the window main% to  be
printed on a portrait page.

DEF PROCuser_redraw(window%,minx%,miny%,maxx%,maxy%,printing%,page%)
IF window%=main% THEN
  x%=50:y%=-100
  IF printing%=TRUE THEN
    x%=FNwimp_worktopaper(x%,0,0)
    y%=FNwimp_worktopaper(y%,1,0)
  ENDIF
  string$="DrWimp printing test."
  PROCwimp_plotwindowtexth(main%,string$,trinity12%,x%,y%,0,0,0,255,255,255,minx%,miny%,maxx%,maxy%)
ENDIF
ENDPROC

We simply keep the same routine but do a work-to-paper coordinate conversion of the plotting 
position if printing% is TRUE.

And thats it!

Now, take a look at another example:

DEF PROCuser_redraw(window%,minx%,miny%,maxx%,maxy%,printing%,page%)
IF window%=main% THEN
  x%=50:y%=-200
  PROCwimp_setforegroundcolour(255,0,0)
  x%=FNwimp_worktoscreen(main%,x%,0)
  y%=FNwimp_worktoscreen(main%,y%,1)
  RECTANGLE FILL x%,y%,100,100
ENDIF
ENDPROC

which will draw a red square with the bottom left corner at the work area coordinates 50,-200. Note 
that it differs from the previous text-plotting case in that it is necessary to convert the work
area  coordinates to screen coordinates for the rectangle plotting action. (Had we plotted a
sprite/drawfile  instead we could use PROCwimp_renderwindowsprite/dfile which would do this work-to-
screen conversion automatically.)

Now here is the modified version which will allow the square to be printed out on a portrait page:

DEF PROCuser_redraw(window%,minx%,miny%,maxx%,maxy%,printing%,page%)
IF window%=main% THEN
  x%=50:y%=-200
  PROCwimp_setforegroundcolour(255,0,0)
  x%=FNwimp_worktoscreen(main%,x%,0)
  y%=FNwimp_worktoscreen(main%,y%,1)
  IF printing%=TRUE THEN
    x%=FNwimp_screentopaper(main%,x%,0,0)
    y%=FNwimp_screentopaper(main%,y%,1,0)
  ENDIF
  RECTANGLE FILL x%,y%,100,100
ENDIF
ENDPROC

That is, when printing% is TRUE, the screen coordinates are converted into paper coordinates - and 
thats all.

One thing to note is that the top left corner of the window main% matches up with the top left
corner  of the paper.

Now for an example of printing the page number at the bottom of each page. You can work out the 
work area coordinates and/or the page coordinates to place the text, but the following example 
assumes the work area of the window main% has been set to the size of an A4 piece of paper. That can 
be done with: width%=FNwimp_lengthtoOS(210,100,0) height%=FNwimp_lengthtoOS(297,100,0)
PROCwimp_resizewindow(main%,width%,height%)

The FNwimp_lengthtoOS calls convert 210mm and 297mm at 100% scale to OS units. The  window is then
resized. The example also assumes the programmer is keeping track of which page is  being displayed
with currentpage%.

Now for the example for a portrait page:

DEF PROCuser_redraw(window%,minx%,miny%,maxx%,maxy%,printing%,page%)
IF window%=main% THEN
  x%=50:y%=FNwimp_getwindowworksize(main%,1)+150
  IF printing%=TRUE THEN
    x%=FNwimp_worktopaper(x%,0,0)
    y%=FNwimp_worktopaper(y%,1,0)
  ENDIF
  string$="Page "+STR$currentpage%
  PROCwimp_plotwindowtexth(main%,string$,trinity12%,x%,y%,0,0,0,255,255,255,minx%,miny%,maxx%,maxy%)
ENDIF
ENDPROC

The text is plotted 150 OS units up from the bottom of the actual paper to allow for printer
borders,  and to give a bit of space. As stated before, currentpage% contains the number of the page 
currently being displayed.

There is one problem with this however. It will be displayed fine, but when it comes to printing
out,  every time currentpage% will contain the page number of the current page being displayed, so
it  won't change on paper. What is required is a way of using the variable page% passed to 
PROCuser_redraw to make currentpage% change, but without corrupting it, so when the  printing has
finished the redraw won't try to show a different page on the screen. Here is one method:

DEF PROCuser_redraw(window%,minx%,miny%,maxx%,maxy%,printing%,page%)
IF window%=main% THEN
  IF printing%=TRUE THEN c%=currentpage%:currentpage%=page%
  x%=50:y%=FNwimp_getwindowworksize(main%,1)+150
  IF printing%=TRUE THEN
    x%=FNwimp_worktopaper(x%,0,0)
    y%=FNwimp_worktopaper(y%,1,0)
  ENDIF
  string$="Page "+STR$currentpage%
  PROCwimp_plotwindowtexth(main%,string$,trinity12%,x%,y%,0,0,0,255,255,255,minx%,miny%,maxx%,maxy%)
  IF printing%=TRUE THEN currentpage%=c%
ENDIF
ENDPROC

If PROCuser_redraw is being called for printing (printing% is TRUE) then currentpage%  is stored in
c% for safekeeping, and set to the number of the page being printed. Then, when the  redraw has
finished, currentpage% is restored to its initial value.




Now for the user method of printing.

Instead of PROCuser_redraw being called, PROCuser_print is called instead, and the page is 
described in much the same way. As there is no window involved you do not need to convert between 
work area, screen and paper coordinates. You simply work in paper coordinates, which are exactly the 
same as OS screen units, with the origin at the bottom left corner of the paper. For example, to
print a  black square, slightly in from the bottom left corner of the paper:

DEF PROCuser_print(minx%,miny%,maxx%,maxy%,page%)
PROCwimp_setforegroundcolour(0,0,0)
RECTANGLE FILL
100,100,50,50
ENDPROC

You can be more precise with your position in real units, for example:

DEF PROCuser_print(minx%,miny%,maxx%,maxy%,page%)
inch%=FNwimp_lengthtoOS(1,100,1)
4cm%=FNwimp_lengthtoOS(40,100,0)
PROCwimp_setforegroundcolour(0,0,0)
RECTANGLE FILL inch%,inch%,4cm%,4cm%
ENDPROC

will print out a black square one inch from the bottom of the page and one inch from the left edge
of  the page, with sides 4cm long.

With PROCuser_print there is no printing% nor currentpage% variable to use because it is  only
called when printing is taking place, and page% holds the current page number of the page  being
printed.

There is a standard clipping rectangle supplied in page coordinates which you can use for 
optimisation, however it is doubtful if the performance gains would be big enough to warrant the
extra  effort of using the clipping rectangle.

When developing the printing part of your application you may like to know of the method used for 
saving on ink and paper when writing DrWimp. A postscript printer was added to !Printers and set it
to  print to a file, thus creating a postscript file. This file was then loaded it into the PD
application  !RiScript which allows you to view postscript files. The output could then be used to
debug and verify  printing code.



25. Window & Icon creation

Creating windows and icons from BASIC instead of loading them from a templates file can sometimes 
have advantages. From a security point of view, if you secure your code, then no-one can change the 
windows and icons. Another advantage is that icons can be created dynamically, say for search
results,  when you want the list to be a set of icons that can be clicked on.

DrWimp provides four functions for creating and deleting windows and icons, which will now be 
described in detail.

The creation of windows and icons requires the use of flags to describe certain aspects of the
window  or icon to be created. With Dr Wimp, the individual one-bit flags are set and unset by using
a single  integer number to represent the flags collectively, and this number is passed as one
parameter to the  wimp-functions. Flags for icons are not the same as flags for windows, but are
passed in the same way,  using a single number.

A flag is represented by a single binary bit, so 8 flags would be represented by 8 bits. For
example:

00101101

This is a binary number with 8 bits. Conventionally, these bits are numbered from the right, from 0 
upwards. So the above example has bits 0, 2, 3 and 5 set (value=1), and the rest unset (value=0).

Binary numbers can be converted into decimal and hexadecimal. The decimal number is obtained by 
adding up each set bit, but with a weighting. The weighting for each bit is 2n, where n is the bit 
number. For example, the binary number we have just looked at is

20+22+23+25 = 45

(recall that bits 0, 2, 3 and 5 are the only ones set).

To convert to hexadecimal is just the same but the bits are taken in fours which are treated as
separate  numbers. So the left-most four (0010) will equal 2 in decimal, and the right-most four
(1101) will  equal 13 in decimal. In hexadecimal A is used for 10, B for 11, C for 12, D for 13, E
for 14 and F for  15. This means the number becomes

2D

in hexadecimal. You can see that each symbol (0-9, A-E) in hexadecimal represents four bits, in the 
same order.

In BASIC this same number could be represented in all three bases as:

%00101101 45 &2D

So any one of those can be passed as the flags parameter to the wimp-functions, as they all
represent  the same number. You may find the binary easiest to use as you can quickly work out what
to put to set  and unset flags.

The function to create windows is

window%=FNwimp_createwindow(vminx%,vminy%,vmaxx%,vmaxy%,wminx%,
                                wminy%,wmaxx%,wmaxy%,flags%,workcol%,
                                button%,title$,maxind%,sarea%)

vminx%, vminy%, vmaxx%, vmaxy% are the screen coordinates that describe the area of screen that  the
visible part of the window will cover when opened. (If you open it centred or centred on the 
pointer or at specific coordinates, then the position vminx% and vminy% on the screen will be 
ignored. However, vmaxx%-vminx% and vmaxy%-vminy% set the width and height of the  window.) The
visible area has to be less than the work area. A window cannot be opened larger than its  work
area!

wminx%, wminy%, wmaxx%, wmaxy% are the work area coordinates that set the work area of the  window.
For example setting them to 0, -100, 200, 0 will create a window whose work area is  200x100 in size
(remember that the work area origin is at the top left so work area y-values are always  negative).

flags% is the number that represents the flags for the window. This is describe in more detail
later.

workcol% is the colour of the work area in desktop colours. So it is a value in the range 0-15, with
1  being the usual value, and 0 giving white.

button% is the button type of the work area. It can be 0 to ignore clicks, and 1 to accept clicks 
(When a click occurs PROCuser_mouseclick will be called with icon -1). (It is hoped that other 
values of button type will be allowed in a later version of Dr Wimp.)

title$ is the title of the window. If it is longer than 12 characters then the title will
automatically  become indirected.

If the title is indirected, then maxind% is the maximum size that the title can be, plus 1.

If sarea% os 0 then the Wimp sprite area is used for the window, otherwise sarea% is the handle  of
a sprite area (just the same as FNwimp_loadwindow).

Flags:
        bit:    meaning if set:
        0       window has title bar
        1       window has close icon
        2       window has back icon
        3       window has horizontal scroll bar
        4       window has vertical scroll bar
        5       window has adjust size icon
        6       window has toggle size icon
        7       window can auto-redraw
        8       window is a pane
        9       window has indirected title

For example

%1011111001 passed as flags% would create a window which has an indirected title, isn't a pane, does
auto- redraws (PROCuser_redraw isn't called), has a toggle size icon, has an adjust size icon, has
vertical  and horizontal scroll bars, doesn't have a back icon or a close icon, but does have a
title bar.  (Remember that the pane item does not affect Dr Wimps ability to use a window as a
pane.)

Returned from the wimp-function is a handle to the window. An example of a basic window is:

main%=FNwimp_createwindow(406,572,790,816,0,-936,1236,0,
                                                %0011111111,1,0,main,5,0)


(Note that the above flag numbers do not line up exactly with those used by the Wimp. It  is hoped
that a later version of Dr Wimp will bring them into alignment. Also, the range  of button type
for windows created in this way is currently restricted in Dr Wimp to  Never  or Click. Again,
it is hoped that a future version will allow this range to be  expanded.)


A similar function can be used to create icons, as follows:

icon%=FNwimp_createicon(window%,wminx%,wminy%,wmaxx%,wmaxy%,
                                flags%,esg%,button%,fcol%,bcol%,font%,
                                text$,sprite$,sarea%,maxind%,valid$)

window% is the handle of the window to create the icon in.

wminx%, wminy%, wmaxx%, wmaxy% are the work area coordinates that define the position of the  icon
and the size. For example using 8,-48,48,-8 will create an icon that is 8 OS units in from the  left
edge of the window, 8 OS units down from the top edge, and 40x40 OS units in size.

flags% is the number that represents the flags for the icon. The flags are:
        
        bit:    meaning if set:

        0       icon has text
        1       icon has sprite
        2       text/sprite is horizontally centred
        3       text/sprite is vertically centred
        4       icon is filled
        5       text/sprite is right justified
        6       icon has border
        7       icon uses an outline font
        8       icon is indirected

For example, passing:

%101001101

in flags% will create an icon that is indirected, doesn't use an outline font, has a border, doesn't 
have right justified text, isn't filled, has vertically and horizontally centred text, doesn't have
a sprite,  but does have text. esg% is the Exclusive Selection Group (ESG) number for the icon.
These are used for radio icons.  All other icons should have this set this to 0.

button% is the button type of the icon.

        button%:                type:

        0               ignore
        1               click
        2               click autorepeat
        3               click/drag
        4               writable
        5               radio
        6               menu
        7               always
        8               release
        9               double-click
        10              release/drag
        11              double-click/drag
        12              double-click/click/drag
        13              reserved
        14              reserved
        15              writable/click/drag

(Note that the flag and button numbers do not line up exactly with the icon flag and  button numbers
used by the Wimp. It is hoped that a later version of Dr Wimp will bring  them into alignment.)

fcol% and bcol% are the foreground and background colours of the icon in desktop colours, so they 
are both in the range 0-15. Usually set to 7 and 1 respectively. Not used if the icon uses an
outline font.

font% is the handle of an outline font, if once is being used. If not then this should be set to 0.

If the icon has some text, then it is put in text$, and if the icon has a sprite, then its name is
put in  sprite$. The sprite area handle is put into sarea%, with 0 denoting Wimp sprite area.

If the icon is indirected, then maxind% is the maximum size of text that can be put plus 1.

valid$ is the icon validation string, which may contain information such as the pointer to use for 
the icon, the acceptable characters for writable icons, the border type, etc.


The function returns a handle to the icon, which is the icon number.

An example, for creating an OK button, is:

okbutton%=FNwimp_createicon(main%,8,-76,136,-8,%101011101,0,1,
                                                7,1,0,OK,,0,3,R6,3)


All this may seem like a lot of effort (and it can be!) but using the !CodeTemps utility in the
Utils  folder, supplied with DrWimp, you can convert window templates containing icons into the
exact  BASIC code to use in calls to FNwimp_createwindow and FNwimp_createicon - plus 
FNwimp_getfont if fonts are used. Full instructions on !CodeTemps is contained in its !Help file.

Windows may be deleted (i.e. their definition removed from the application) using:

PROCwimp_deletewindow(main%)

which will delete the window whose handle is main%. If the window was open then it will be closed. 
One point to note though is that not all memory used by the window is reclaimed. The memory used to 
store indirected data remains tied up for good, so a lot of creating and deleting windows will 
eventually result in running out of memory.

Icons can be deleted using PROCwimp_deleteicon, for example:

PROCwimp_deleteicon(main%,2,0)

will delete icon 2 from the window main%. The icon will not disappear immediately though as the 
window needs to be redrawn. This can be done automatically by setting the third parameter to 
PROCwimp_deleteicon to 1, to cause a redraw. Eg:

PROCwimp_deleteicon(main%,2,1)

Finally, it is worth noting that you can create an icon with zero width/height, which can sometimes
be  of use. But if, in this state, you want it disappear completely from the screen make sure it is
un-filled  and has no border.



26. Stopping a desktop quit

It is possible to prevent the application quitting if there is unsaved data in the application. An 
application can be caused to quit by either calling PROCwimp_quit, or the user choosing Exit or 
Shutdown from the Task Manager menu.

Copy the file Template7 from the Tutorials folder into !MyApp and rename to Templates.

We will use the variable asterisked% to show if data is unsaved, TRUE indicating data needs saving, 
and FALSE if not (we will not bother with the actual saving code). We start with no data needing 
saving, so add the following line to PROCuser_initialise:

asterisked%=FALSE

We also need to load in our window which will warn of a desktop shutdown. Add this line where the 
main window is loaded:

warn%=FNwimp_loadwindow("<MyApp$Dir>.Templates","warn",0)

Clicking the OK button of the main window will constitute a change, so the title bar needs to be 
asterisked and the value of asterisked% set to TRUE. Add the following to  PROCuser_mouseclick:

IF window%=main% AND icon%=2 AND asterisked%=FALSE THEN asterisked%=TRUE
   PROCwimp_putwindowtitle(main%,FNwimp_getwindowtitle(main%)+"*")
ENDIF

Run !MyApp, open the main window and click the OK button. An asterisk should appear on the title 
bar.

FNuser_quit is used to handle the application being quit. Returning a 1 allows the quit to take 
place, whereas returning a 0 stops the quit. The following typical code should be added to 
FNuser_quit:

DEF FNuser_quit(type%) Return%=1 IF asterisked%=TRUE THEN
        PROCwimp_menupopup(warn%,2,0,0)
        quittype%=type%
        Return%=0
ENDIF
=Return%

Passed to FNuser_quit is the variable type% which indicates the type of quit that is happening, 
i.e. application is quitting or the desktop is being shut down. Here, we are not really interested
in what  type of quit it is, but we need to keep a record so we can restart the same type of quit
later.

The warn window is opened, centred on the screen, and 0 is returned to stop the quit. Note that the 
window was opened with PROCwimp_menupopup, which is for opening menus. As was noted  before, windows
can also be opened with it, the result being that clicking anywhere else on the screen  will
automatically close the window.

All that needs to be done now is to respond to the Cancel and Discard buttons. Clicking Cancel 
will close the window. Clicking the other button will restart the quit, using PROCwimp_quit. Add 
the following to PROCuser_mouseclick:

IF window%=warn% and icon%=0 THEN
  asterisked%=FALSE
  PROCwimp_quit(quittype%)
ENDIF
IF window%=warn% and icon%=2 THEN PROCwimp_closewindow(warn%)

Run !MyApp. Trying to quit the desktop after clicking OK in the main window stops the quit, and 
allows the user to choose what happens next via the warning window.

Clicking on Discard, which is icon 0, sets asterisked% to FALSE to indicate there is no longer 
any unsaved data, as it has been effectively discarded. PROCwimp_quit is then called with the type 
of quit that was originally started, and passed to FNuser_quit. The result is that FNuser_quit is 
called again, but this time asterisked% is FALSE so the function will return 1 to continue with the 
quit.

If you have any cleaning up to do in your application when it quits, such as losing fonts, then that
code can be placed at the end of FNuser_quit, after the check to see if  asterisked% is TRUE.



27. Dynamic Areas

Often it is desirable to be able to load in data of various types, and not have a limit on the
amount of  data that can be loaded in. The block of memory that is used is traditionally created
with something  like:

DIM block% 2048

which creates a block, called block%, 2048 bytes in size. The main problem with this is that the
size  of the block, and hence the maximum size of data that can be loaded in is hard-wired into
the  program. One solution to this is to put the size into the !Run file by using:

Set MaxSize 2048

and then reading it into the program with FNwimp_getsysvariable and creating the block.  However,
this requires that the user might have to edit the !Run file, and if all they want to do is just 
use the program, not change files, then this solution is not ideal.

A dynamic area is a block of memory, just like the example defined above, but can shrink and expand 
in size. The memory is taken from and returned to the free application memory pool as the block 
changes size, thus the only limit with the size of a dynamic area, is the amount of memory in the 
machine.

On versions of RISC OS 3.5 and better, an application can create its own, separate dynamic areas, 
which appear in the Task Manager. These will be referred to as ADAs, for Application Dynamic Areas. 
This facility is not available on RISC OS 3.10, but the Module Area (RMA) can be used instead. This 
is a dynamic area where modules are loaded into and removed from.

The DrWimp dynamic area functions have therefore been written to use both the RMA and ADAs 
transparently. This means you can write your application to use the RMA when it is run on RISC OS 
3.10, and ADAs when it is run on RISC OS 3.50+, without any difference to the function calls or the 
way the application operates.

To your application the RMA and ADAs appear identical, but there is an important difference that you 
might have to take into account. When your application creates an ADA, it is just for your
application,  and you can shrink and expand it is required. The RMA however is used by RISC OS and
other  applications which might be using the RMA in the same way. This means that if you create a
dynamic  area in the RMA, and then a module is loaded or another application creates a dynamic area
in the  RMA, and then you delete your area, the RMA has a hole in it where your area was. This
cannot be  returned to the free application memory pool, but only used for subsequent requests for
blocks of  memory in the RMA. The same thing happens when you enlarge your dynamic area. It has to
be  moved and remade in another part of the RMA, thus leaving a hole. This is called fragmentation
and  leads to the slow eroding of the computer's free memory. If you are concerned about
fragmentation, especially if you are enlarging dynamic areas a lot, and you  are using RISC OS 3.5+,
you can force DrWimp to create dynamic areas in the RMA, so you can see  how your application will
behave on older machines.

DrWimp provides four wimp-functions for the creation, management and deletion of dynamic areas.  The
following example creates a dynamic area 1024 bytes in size, using the RMA on older machines  and an
ADA on newer ones, with the name Test Area:

block%=FNwimp_createdynamic(1024,0,0,"Test Area")

block% is the handle to the area, and is also the base address, just as if you had done:

DIM block% 1024

The initial size can be 0 bytes, but RISC OS may create dynamic areas that are always at least 4Kb
in  size anyway.

Now you can store data in the block, such as drawfiles, sprite files, or anything you like. First
though  you need to make sure the area is the correct size. The following section of code loads a
sprite file  whose pathname is in path$, into the dynamic area we just saw how to create:

size%=FNwimp_measurefile(path$)
block%=FNwimp_changedynamic(block%,1,size%)
d%=FNwimp_loadsprites(path$,block%)

The dynamic area is resized to the size of the sprite file and returned is a new handle to the
dynamic  area. Then the sprite file is simply loaded in to the area. From there it can be rendered
in a window or  whatever.

Size changes for dynamic areas can be relative or absolute. The previous example showed the area 
being set to an absolute size, which was the size of the sprite file. However, it could have been 
increased by 1024 bytes using:

block%=FNwimp_changedynamic(block%,0,1024)

or shrunk by 1024 bytes with:

block%=FNwimp_changedynamic(block%,0,-1024)

When the dynamic area is finished with, it must be deleted. For example:

PROCwimp_deletedynamic(block%)

Finally, the current size of a dynamic area in bytes can be obtained with:

size%=FNwimp_measuredynamic(block%)

(Note: From Version 3.55 onwards any dynamic areas created by your application will be deleted
automatically when you quit the application.)

28. Colour picker

Please note that although Version 3.54 of Dr Wimp is expected to work with  RiscOS Versions earlier
than 3.50, they will not be able to use the Colour Picker  wimp-functions described below. If you
are using an earlier RiscOS Version there  is no need to change anything to compensate for this -
just dont call the Colour  Picker wimp-functions! If you have a RiscOS Version from 3.50 onwards
you will be familiar with the Colour Picker window,  from applications such as !Draw - and now Dr
Wimp will enable you to introduce the same features  into your own applications.

Essentially, the Colour Picker is a window which, when displayed, enables the application user to 
choose, visually, what colour is required, from the complete range of colours available. A colour
can  be specified by clicking on the colour actually displated in the window, or by specifying the 
proportions of the constituent colour components (in RGB, CMYK or HSV terms). These are all 
automatically linked in the Colour Picker window, so a simple but very comprehensive facility is 
offered.

Dr Wimp provides two ways of harnessing the Colour Picker: one by opening the colour picker  window
exactly like any other window and the other by opening it as a sub-menu from a menu item. 

When the colour picker window is first opened, it will have a default colour already displayed and
Dr  Wimp allows you to specify this. Further, you can choose between specifying this initial colour
in  familiar rgb values in the range 0-255 or in the values of one of the three colour models
i.e. in the  RGB or CMYK or HSV colour model. Whichever method you choose here will not limit you 
subsequent ability to use the whole range of the colour picker window settings once the window is 
open - which includes being able to change the model etc.

Briefly:

The RGB colour model specifies the amounts of the Red, Green and Blue components  of a colour in
percentage terms i.e. each in the range 0-100. (Note: not 0-255 here.)

The CMYK model specifies the amounts of the Cyan, Magenta, Yellow and Key  (black) components of
a colour in percentage terms i.e. each in the range 0-100.

The HSV model specifies the amounts of the Hue colour angle in the range 0-359  degrees, and the
Saturation and Value components of a colour in percentage terms (0- 100).

These different models are merely different ways of specifying a colour and each tends  to be used
in practice by different groups of people working with colour e.g. artists,  printers, scientists.

Once you have decided which colour you want, you need a means of extracting the choice from the 
colour picker window and into your program for further use e.g. to draw something in the chosen 
colour. Dr Wimp provides two user-functions for this purpose. One provides the chosen colour output 
in 0-255 rgb values and the other in the values of the model actually selected in the colour
picker  window at the time the selection was made.

If you open the colour picker window as a sub-menu it will, as you would expect, close 
automatically like any other sub-menu if you move the pointer back over the menu item from which it 
came - and if you click elsewhere on the screen. This is known as the sub-menu dialogue type.

If you open the colour picker window as an ordinary window, Dr Wimp also allows you to have the 
choice of closing it in the normal way (e.g. by clicking on its Close icon) or closing like a menu
i.e.  closing when a click is made elsewhere.

In all cases, the window will close automatically when you use <select> over the colour picker 
windows OK or None buttons (but using <adjust> will keep it open as usual).

Now we can look at the wimp- and user-functions and we will start with the latter.

They are:
    
    PROCuser_colourpickerrgb(red%,green%,blue%,none%)
and
    PROCuser_colourpickermodel(model%,value1%,value2%,value3%,value4%,none%)
 
Both of these are called automatically every time you make a colour selection in the colour picker 
window i.e. when you press OK or None.

If you pressed OK, then both user-functions will pass the values of the chosen colour in their 
parameters and none% will be set to 0. If you pressed None, then the currently displayed colour 
values in the colour picker window will still be passed, but none% will be set to 1. (So it is up to
you  to decide how to react to none% having a value of 1. For example, you might want to ignore the 
colour data in this case, or  you might want to store the values in order to open the window with
these  values next time.)

Irrespective of the method you chose to open the colour picker window and irrespective of the actual 
model currently selected in the window at the time you made your colour choice, 
PROCuser_colourpickerrgb will always give the values red%, green% and blue% in the  range 0-255,
which is often used in other wimp-functions and can therefore be conveniently passed on  directly.
The parameters passed in PROCuser_colourpickermodel need a little extra explanation. They  will
reflect the chosen colour values in the model actually displayed in the colour picker window at 
the time the OK (or None) button is pressed - which, of course,  may not be the same model in
which  you specified the window to open initially.

model% will be either 0, 1 or 2 for RGB, CMYK or HSV respectively.

value1%, value2%, value3% and value4% will be in percentage values in the range 0- 100 - except that
value1% will be in the range 0-359 if model% is 2 (i.e. the  colour angle in degrees in the HSV
model). Also, value4% only has relevance  for the CMYK model i.e. when model% is 1 - and it will
be set to -1 for other  models.

Now let us look at opening the colour picker window - firstly as a normal window.

The two available wimp-functions are:

PROCwimp_opencolourpickermodel(model%,dialoguetype%,value1%,value2%,value3%,value4%,x%,y%)

and

PROCwimp_opencolourpickerrgb(dialoguetype%,red%,green%,blue%,x%,y%)

From the earlier description of the user-functions, the meaning of most of these parameters will now 
be clear. The values set the colour that will be initially displayed when the window first opens and
also  the model that will be initially displayed. (If you use PROCwimp_opencolourpickerrgb the 
RGB model will be displayed initially with the 0-255 values converted to 0-100 values). Dont
forget  that value4% must always have a value assigned to it although that value will be ignored if 
model% is 0 or 2.

x%/y% are simply the required work area OS coordinates for the top left corner of the opening colour 
picker window.

The parameter dialoguetype% determines the type of window closure that will apply and can be  set to
either 0 or 1. If it is 0 then the colour picker window will stay open until you close it by some 
means or you press OK or None. (This is called the normal dialogue.) However, if it is 1 then the 
window will also close if you click anywhere outside it. (This is known as the menu dialogue, for 
fairly obvious reasons.)

With either of these two wimp-functions, you simply call them in similar circumstances to using 
PROCwimp_openwindow. For example, from PROCuser_mouseclick or PROCuser- menuselection. They are
perfectly straightforward to use. (You do not normally need to know the  colour picker window handle
but it is held, after the call, in the global variable wpickerwindow%.)

Opening the colour picker as a sub-menu is also easy, but involves two steps.

A special global variable called wSUBMENUCOLOURPICKER% (a mouthful, but you wont easily  forget
it!) has been created in the DrWimp library and is set to 1 as default. If you want the colour 
picker window to appear as a sub-menu to an (already defined) parent menu item, then the first step
is  to attach wSUBMENUCOLOURPICKER% to that item as its sub-menu/window handle. e.g.:

PROCwimp_attachsubmenu(parentmenu%,3,wSUBMENUCOLOURPICKER%)

This action ensures that the required item (here, 3) on the parent menu (whose handle here is 
parentmenu%) correctly displays a sub-menu arrowhead - and that is all it does.

The second, and final, step is to decide which of two wimp-functions you wish to use to actually
cause  the window to open (when you move across the just-created arrowhead) and put it into 
DEFPROCuser_overmenuarrow. The two wimp-functions are:

PROCwimp_opensubmenucolourpickermodel(model%,value1%,value2%,value3%,value4%,x%,y%)

and

PROCwimp_opensubmenucolourpickerrgb(red%,green%,blue%,x%,y%)

As you can see, these match the two previously-described wimp-functions except that there is no 
dialoguetype% parameter (because, in this case, the colour picker window will always act  exactly
like a sub-menu i.e. it will use the sub-menu dialogue).

A typical coding might be:

DEF PROCuser_overmenuarrow(nextsubmenu%,parentmenuitem%,x%,y%)
CASE nextsubmenu% OF
        WHEN wSUBMENUCOLOURPICKER%
        PROCwimp_opensubmenucolourpickermodel(1,0,40,55,20,x%,y%)
ENDCASE
ENDPROC

Its as easy as that.

This would cause the colour picker window to open when you move across its parent menus  arrowhead
- and, here, it would open with the CMYK model showing percentage values of 0, 40, 55  and 20,
which is an orangey sort of red. It will open in the same place as a conventional sub-menu,  because
x% and y% have been passed straight through.

As before, the two colour picker user-functions will be called when you actually select OK or None. 
(If you did not change the above initial colour and then selected OK,  PROCuser_colourpickerrgb
would return 204, 102 and 64 for its red, gren and blue values i.e.  in the range 0-255.)



29. Wimp messages

The Wimps messaging system is a means used by the Wimp to manage multi-tasking applications 
effectively. It is particularly important for handling file tranfers e.g. saving/loading/printing.
The  DrWimp library routinely receives all these messages and acts on many of them, but does not
(yet?)  use them all.

For the vast majority of circumstances this messaging system will be entirely hidden from Dr Wimp 
users (thats the whole point!) but for some advanced operations it can be useful for any messages
that  are received by your application but unused by the DrWimp library to be passed on to the
programmer  via a user-function. This is the purpose of DEF FNuser_wimpmessage(messagenumber%). 
When it is called, the unused wimp-message number will be in the only parameter.

However, because there are frequent wimp-messages, the option to pass on the unused messages is 
provided with an on/off switch - and this is set to its default value of off at application
start-up.

The switch is controlled very simply by the special global variable UNUSED%. This is set to FALSE 
within FNwimp_initialise, on application start-up, but you can set it to TRUE at anytime after  that
(including within PROCuser_initialise, if you wish).

During any time that UNUSED%=TRUE the message number of any wimp-messages received but not  used
within the DrWimp library will be passed via the single parameter of FNuser_wimpmessage  for you to
detect and act upon if you so wish.

For your information, the current version of the DrWimp library uses the following wimp-messages, 
so these values will never be passed via FNuser_wimpmessage:

0
&1
&2
&3
&5
&8
&A
&502
&400C0
&400C1
&400CC
&47700
&47702
&80147


30. Iconiser

Iconising is the result you get on pressing a windows Close icon whilst holding down <shift> i.e. the 
window is converted to an icon on the Pinboard, from whence it can be re-opened by double-clicking 
on it (see User Guide). With later versions of RISC OS the same can be achieved by pressing a special 
iconiser button on the window furniture.

From Dr Wimp Version 3.55 your application responds to the Wimps iconiser protocol in a 
customised way and allows you to alter the text and sprite used. It does this by calling 
PROCuser_iconise whenever iconising action takes place.

If you do nothing, the iconised sprite will be the default one supplied by the Wimp (a framed question 
mark for an application window) and the text beneath it will be the name that you used for your 
application in FNwimp_initialise e.g. YourApp

However, if you want to use a customsed sprite and/or different text, then all you need to do is set the 
names of them in PROCuser_iconise, as follows. You will note that the skeleton !RunImage contains:

DEF PROCuser_iconise(window%,RETURN text$,RETURN sprite$)
ENDPROC

When called by the DrWimp library, these parameters will contain the window handle where the 
iconising action has taken place plus a default text and default sprite name. The text is straightforward: 
as mentioned above, the default text will be your application name as put in FNwimp_initialise. 
(The default sprite name will also be the same text, but reduced to the leftmost seven characters if it 
was longer than seven.)

However, for iconising, the Wimp always uses sprites whose name begins with the prefix ic_ e.g. 
ic_draw or ic_yourapp etc. The prefix ic_ is added automatically by the Wimp. So, 
sprite$ only needs to contain the wanted sprite name without the prefix e.g. if your applications 
declared name is YourApp then, when PROCuser_iconise is called, the default name in 
sprite$ will be YourApp. (And note that if the application is called LongerName, the 
default sprite$ will be LongerNa.)

If you do nothing then the contents of sprite$ will not change and the Wimp will be looking for an 
iconiser sprite called ic_yourapp (or ic_longerna) - sprites are not case-sensitive. If it 
finds one with the right name it will use it. Otherwise it will use the Wimps own default iconiser icon.

Conversely, to demonstrate iconiser customisation, lets say that you want the text beneath the 
iconised window (whose handle is main%) to be YourAppMain and you want a sprite called 
ic_neat to be used. You would effect this simply by using something like:

DEF PROCuser_iconise(window%,RETURN text$,RETURN sprite$)
CASE window% OF
WHEN main%
	text$=YourAppMain
	sprite$=neat
ENDCASE
ENDPROC

and, of course, you would have to supply sprites called ic_neat in the !Sprites/!Sprites22 files. 
Thats all there is to it.  You can easily see that this can be used to show a different text and/or sprite 
for each of your applications windows, if you wish.

It is important to note that the Wimp does not allow sprite names to be greater than 10 characters. 
Hence it is vital that the name you use in sprite$ above does not exceed 7 characters - to allow for 
the prefix ic_. If the overall sprite name length does exceed 10 characters then the Wimp will 
truncate the name to the leftmost 10 characters and try to find  a sprite file to match. If it cannot find 
one, the default iconiser sprite will be used instead. From Version 3.56, you will be warned if your 
intended sprite name is too long.

(If you use !Fabricate - see Section 2.33 - the resulting customised skeleton application will include a 
rough (very!) sprite for this purpose, called ic_myapp - which is also included in the !MyApp 
skeleton. !Fabricate will also warn you about, but not prevent, your application name exceeding 7 
characters.)



31. Grubby tasks

You will sometimes see tasks that load onto the iconbar, but when the icon is clicked on they leave
the  desktop and monotask. When the user has finished, they are returned to the desktop, with the 
application still loaded onto the iconbar. Acorn calls these tasks Grubby tasks, and they are very 
simple to implement with Dr Wimp.

Alter PROCuser_mouseclick so it has a line like:

CASE window% OF
        WHEN bar% :
        PROCwimp_starttask(BASIC -quit <MyApp$Dir>.Mono)
ENDCASE

Create a BASIC file called Mono inside the !MyApp directory containing the following:

MODE12
PRINT This is monotasking!
A$=GET$
*DESKTOP
END

Re-load !MyApp and click on the iconbar icon. Press a key to return to the desktop. Note: change the 
mode number to one suitable for your monitor.

You will probably want to mangle up the second BASIC file as well as !RunImage with DrWimp to  give
you more security. This is possible if you dont use DrWimp in the second BASIC file. Mangle it  up
with !MakeApp2 and !Crunch in the usual way, and then change the PROCwimp_starttask to  something
like:

PROCwimp_starttask(Run <MyApp$Dir>.Mono)



32. Bits & bobs

Here are a few other useful points.

Directory paths/Leafnames

Sometimes it can be useful to get a directory path or a leafname from a pathname.

If the pathname is:

IDEFS::Andy.$.Progs.Project1.!Wow.Sprites

then the the directory path is IDEFS::Andy.$.Progs.Project1.!Wow.  (Note the trailing fullstop.)

and the leafname is Sprites

DrWimp can extract these names for you with:

FNwimp_getdirectorypath(path$)

which returns the directory path, including the trailing fullstop (or trailing colon if something
like Boot:!Help is the full path) and:

FNwimp_getleafname(path$)

which returns the leafname.


Caret location

FNwimp_getcaretposition returns information about the current location/position of the caret.
Currently, five items of information are available: the handle of window and icon with the caret in 
them; the x and y work area coordinates of the caret in a window; the position (index) of the
caret  within the text of a writable icon.


DrWimp library version number and upgrades

The DrWimp library periodically gets upgraded with modifications or improvements and this can  mean
that applications which you have made with earlier versions may not work properly (or at all) if 
you try to substitute the new DrWimp library.

To protect against this, there is a wimp-function to read the version number of the library. So, for 
example, at the start of your program you could add a short routine to read the library version
number  and alert you if it is not the same one as you used to create the application.

The wimp-function is FNwimp_libversion and it returns the DrWimp library version number x  100. So,
if it is Version 3.53 then it will return 353.

Dont forget that there is no need to use any later DrWimp version with an application that is
working  to your satisfaction with an earlier version - even less need if you have used the
post-programming  utilities such as !Linker, etc.

However, if/when you decide to upgrade your application then it will probably make sense to use the 
then latest Dr Wimp version to do it and you can start by incorporating the new DrWimp version 
before making other changes. Always read the Upgrade file - within the Documents folder - to see 
what changes (if any) will need to be made to applications constructed with previous DrWimp library 
versions. Usually, where changes are necessary, they are very simple to do.

Of course, if you are starting a new application then it always makes sense to start with the latest 
version of Dr Wimp.

It is probably obvious, but in any complete version of the Dr Wimp package, the !Fabricate utility
will  always produce its skeleton application using the !RunImage/DrWimp library version of that
package.


Resizing windows

PROCwimp_resizewindow resizes a window to the supplied width and height. The work area is 
set to the new values. If it is smaller than the current visible area, then the window will shrink. If the 
new size is larger the visible area will not alter (i.e. the window will be scrolled to show the same size 
as before. Use PROCwimp_resizewindowvisible to alter displayed size.)


Icon text colours

PROCwimp_colouricontext changes the colour of some text in an icon to one of the standard 16 
desktop colours. This means that you can grey-out labels which are not filled. If you do that with 
PROCwimp_icondisable then the unfilled background turns white.


Icon size and position

FNwimp_geticonsize is like FNwimp_getwindowsize in that is returns the dimensions of an  icon - and
FNwimp_geticonposition returns the work area position of an icon.


Icon state (selected/de-selected)

FNwimp_geticonstate is the complement of PROCwimp_iconselect, and returns a 1 if the  icon is
selected, or a 0 if it isn't.


Graphics colours

PROCwimp_setforegroundcolour and PROCwimp_setbackgroundcolour set the  current GCOL colours for
drawing, and use dithering if the exact colour is not available in the current  mode.


Storing strings in memory blocks

Blocks can be used as a compact way of storing strings, if you know the maximum length for a string.

block%=FNwimp_createblock(10,25)

Will create a block that can store 10 strings, any of which can be up to 25 characters in length. 
block% is the handle to the block.


PROCwimp_putinblock(block%,"A string",3)

Will put the string shown into position 3 in the block, whose handle is block%.


s$=FNwimp_getfromblock(block%,3)

Will extract the string from position 3 in the block whose handle is block%.


Hourglass

PROCwimp_hourglasson and PROCwimp_hourglassoff turn the hourglass on and off  respectively. The
percentage display on the hourglass can be set using  PROCwimp_hourglasspercentage.

Desktop save

From Dr Wimp Version 3.54 you have the option to choose whether or not your application responds  to
the Wimps desktop save protocol.

This protocol means that if a user selects Desktop save  from the Task Manager iconbar menu whilst 
your application is running then - if you have chosen to activate the option -  your application
will be  duly entered into the list of tasks to be run automatically on future start-ups. (See User
Guide for more  details on desktop save.)

The option is exercised on task initialisation by setting the fourth (final) parameter of 
FNwimp_initialise. Seting this parameter to 0 disables the action: setting it to 1 enables the 
action. See Section 2.1 also.




33. Saving time with !Fabricate

You will find that after writing a few applications, in most if not all you are having to find a
templates  file with an info window in it, rename the sprites and all occurrences of MyApp to your
application's  name, create an iconbar icon and iconbar menu, fill in the details in the info
window, set the version,  etc, etc.

Doing this routine work over and over again gets tedious, hence the utility !Fabricate in the Utils 
folder. It can do all those things for you and save boredom setting in, leaving you to get on with 
writing the interesting parts. It also allows you to customise the output a little.



34. Final comments

Sections 1 and 2 of this Manual are designed to get you up and running. They do not cover every 
aspect of using Dr Wimp. Many other features of DrWimp are demonstrated by the examples in the 
Examples folder. Their !RunImage files are well commented to show what is being done and why.

Section 3, which follows, contains information about every user- and wimp-function available in the 
Version indicated on the Front Cover of the Manual.

Good programming!

Dont forget: suggestions for future additions, bug reports and help requests are always very
welcome,  either by E-mail or post.

Also, the latest version of DrWimp can be obtained from the web page below:

        World Wide Web: http://www.argonet.co.uk/users/rayfavre/

or directly from:

        Email: rayfavre@argonet.co.uk
        Post: Ray Favre, 26 West Drayton Park Avenue, West Drayton, Middlesex, UB7 7QA, U.K.
                (An SAE would be appreciated.)




Section 3 Functions


1. Misc

FNwimp_OStolength(coord,scale,inch%)
Converts OS units to mm or inches.
coord = value to convert, can be integer or floating point.
scale = scaling factor 0-100 (%) can be integer or floating point.
If inch%=0 the value returned is in mm. If inch%=1 the
value returned is in inches.

FNwimp_changecase(string$,upper%)
Converts a string all to upper or lower case characters.
string$ = string to convert
If upper% = 0 then conversion is to lower case
If upper% = 1 then conversion is to upper case
(The conversion only affects the alphabetical characters A-Z and a-z.
All others are left unchanged.)

FNwimp_createblock(items%,length%)
Creates a block for storing strings in. Returns a handle
to the block.
items% = maximum number of strings to store.
length% = maximum possible length of each string.

FNwimp_decplacesnum(number,decplaces%)
Returns, as a real number, the number formatted to the designated
number of decimal places.
number - is the number to format, can be integer or floating point.
decplaces% - is the number of decimal places required.
(N.B. this function can suffer from rounding errors. Use the string
version FNwimp_decplacesstr if possible.)

FNwimp_decplacesstr(number,decplaces%)
Returns, as a string, the number formatted to the designated number of
decimal places.
number - is the number to format, can be integer or floating point.
decplaces% - is the number of decimal places required.

FNwimp_errorchoice(title$,error$,prefix%)
Reports an error using a standard error box.
It has both OK and CANCEL buttons.
title$ = title of error window.
error$ = error message.
If prefix% = 0 then the title is title$.
If prefix% = 1 then the title is prefixed by Error from .
If prefix% = 2 then the title is prefixed by Message from .
Returns TRUE if OK pressed. FALSE if CANCEL pressed.

FNwimp_getdirectoryobjectname(dir$,objectnumber%)
Returns name of specified object (i.e. file/application/directory) in
specified directory.
dir$ - full pathname of directory or application
(NOTE: Will give error if dir$ is not a directory or application)
objectnumber% is 1 for first object, 2 for second object, etc.
Objects are read in alphabetical order of name - so names starting
with ! (Ascii 33) will come first.
(Use FNwimp_countdirectoryobjects first to find total number of 
objects present in directory.)

FNwimp_getdirectoryobjecttype(dir$,objectnumber%)
Returns, as a string, the filetype number of specified object (i.e.
file/application/directory) in specified directory. A file will
return &xxx where xxx is the filetype hex number e.g. &fff for 
textfiles.
A directory will return &1000 and an application &2000.
dir$ - full pathname of directory or application
(NOTE: Will give error if dir$ is not a directory or application)
objectnumber% is 1 for first object, 2 for second object, etc.
Objects are read in alphabetical order of name - so names starting
with ! (Ascii 33) will come first.
(Use FNwimp_countdirectoryobjects first to find total number of 
objects present in directory.)

FNwimp_getdirectorypath(pathname$)
Returns the pathname with the leafname removed i.e. returns the 
directory specification string. The trailing fullstop (or trailing colon, if 
pathname$ is something like Boot:!Help) will be included.
pathname$ = full file pathname string
(If pathname$ does not include at least one . character a null-string 
will be returned, after a warning.)

FNwimp_countdirectoryobjects(dir$)
Returns number of objects (i.e. files/applications/directories) in
specified directory.
dir$ - full pathname of directory or application
(NOTE: Will give error if dir$ is not a directory or application)

FNwimp_getfromblock(block%,pos%)
Returns a string stored in a block.
block% = handle of block.
pos% = position of string in block (ranging from 1 to
maximum as passed to FNwimp_createblock).

FNwimp_getleafname(path$)
Returns a string containing the leafname from the pathname.
path$ = pathname.

FNwimp_getscreenres(direction%)
Returns the resolution (number of pixels) of the current screen mode
in the specified direction.
If direction%=0 then return is horizontal resolution.
If direction%=1 then return is vertical resolution.

FNwimp_getscreensize(side%)
Returns the required dimension, in OS units, of the full screen in
current mode.
If side% = 0 returns width.
If side% = 1 returns height.

FNwimp_initialise(name$,wimpmem%,ver%,desktopsave%)
This function registers your application with the Task Manager, reserves
some important memory and determines if the application will
give a response to the Wimps desktop save protocol and whether it will 
pass on unused messages from the Wimps messaging system.
name$ = the name of your application eg. MyApp.
wimpmem% = number of bytes to reserve for window, icon and menu 
definitions. (Space for indirected data is allocated automatically.)
ver% = minimum version of RISC OS that the application is allowed to 
run on, multiplied by 100.
If desktopsave% <> 0 then application will respond to Wimps desktop 
save message.

FNwimp_lengthtoOS(coord,scale,inch%)
Converts mm or inches to OS units.
coord = value to convert, can be integer or floating point.
scale = scaling factor 0-100 (%) can be integer or floating point.
If inch%=0 the value coord supplied is in mm. If inch%=1
the value coord supplied is in inches.

FNwimp_libversion
Returns the version number of the DrWimp library x 100.
Eg. if the version of the library is 3.54 then 354 will be returned.

FNwimp_roundfloat(float)
Rounds the specified floating point number up or down and returns the
integer.

FNwimp_screentowork(window%,coord%,side%)
Converts the x or y screen coordinate coord% to a work area x or y 
coordinate - all in OS units.
window% = handle of window whose work area coordinate is being 
sought.
coord% = coordinate (x or y).
If side% = 0 then coord% is a x coordinate, and an x coordinate is 
returned.
If side% = 1 then coord% is a y coordinate, and a y coordinate is 
returned.

FNwimp_sigfigsnum(number,sigfigs%)
Returns, as a real number, the number formatted to the designated
number of significant figures.
number - is the number to format
sigfigs% - is the number of significant figures required.
(N.B. this function can suffer from rounding errors. Use the string
version FNwimp_sigfigsstr if possible.)

FNwimp_sigfigsstr(number,sigfigs%)
Returns, as a string, the number formatted to the designated number of
significant figures.
number - is the number to format
sigfigs% - is the number of significant figures required.

FNwimp_getsysvariable(sysvar$)
Returns, as a string, the contents of the system variable sysvar$.
Note < and > are not required in sysvar$.
If designated system variable is not present a null string is returned.

FNwimp_testsysvariable(sysvar$)
Returns TRUE if designated system variable is present, or FALSE if not.
Note < and > are not required in sysvar$.

FNwimp_worktoscreen(window%,coord%,side%)
Converts the x or y work area coordinate coord% to an x or y screen
coordinate - in OS units
window% = handle of window whose work area coordinate is being 
converted.
coord% = coordinate (x or y).
If side% = 0 then coord% is a x coordinate, and an x coordinate is 
returned.
If side% = 1 then coord% is a y coordinate, and a y coordinate is 
returned.

PROCwimp_bar(window%,icon%,length%,dir%)
Sets/adjusts the length of a bar - in OS units.
window% = handle of window containing the bar.
icon% = icon number of the bar.
length% = length of the bar.
If dir% = 0 then the bar moves horizontally keeping the height constant.
If dir% = 1 then the bar moves vertically keeping the width constant.

PROCwimp_error(title$,error$,button%,prefix%)
Reports an error using a standard error box.
title$ = title of error window.
error$ = error message.
If button%=1 then will have an OK button.
If button%=2 then will have a CANCEL button.
prefix% = 0 then the title is title$.
If prefix% = 1 then the title is prefixed by Error from .
If prefix% = 2 then the title is prefixed by Message from .

PROCwimp_hourglassoff
Turns off the hourglass.

PROCwimp_hourglasson
Turns on the hourglass.

PROCwimp_hourglasspercentage(percentage%)
Sets the percentage display on the hourglass.
percentage% is in the range 0 to 99.

PROCwimp_increaseslot(bytes%)
Increases size of wimpslot by bytes% bytes. If not
enough available RAM then creates an error.

PROCwimp_putinblock(block%,string$,pos%)
Stores a string in a block. (The block must have been created using 
FNwimp_createblock).
block% = handle of block.
string$ = string to store.
pos% = position to store string in (ranging from 1 to maximum number 
of strings as passed to FNwimp_createblock).

PROCwimp_quit(type%)
Causes the application to quit or the desktop to be
shutdown. FNuser_quit will be called with type% passed to it.
If type%=0 the application will quit.
If type%=1 the desktop will be shutdown.

PROCwimp_setforegroundcolour(red%,green%,blue%)
Sets the current GCOL foreground colour to the nearest possible for
the current mode.
red% = amount of red in range 0-255.
green% = amount of green in range 0-255.
blue% = amount of blue in range 0-255.

PROCwimp_setbackgroundcolour(red%,green%,blue%)
Sets the current GCOL background colour to the nearest possible for
the current mode.
red% = amount of red in range 0-255.
green% = amount of green in range 0-255.
blue% = amount of blue in range 0-255.

PROCwimp_starttask(command$)
Sends command$ to the CLI. Omit *.


2. Polling

PROCwimp_poll
This function provides the main loop of your application.
When it has exited, your application has quitted.
During the loop operation, whenever something happens to your
application eg. an icon has been clicked on, then the relevant
action will be initiated from the loop.

PROCwimp_pollidle(seconds%)
If NULL%=TRUE then PROCuser_null will be called every
seconds% seconds instead of every time control is passed
to the application and no event has occurred.

PROCwimp_singlepoll
The same as PROCwimp_poll, except that it is called once
and not in a loop. If something happens then the relevant action will
still be taken before returning.
Useful for making loops multitask, eg: raytracing,
printing, calculating, loading in data, etc.
Note: if calling in PROCuser_null, make sure NULL%=FALSE
before this call is made (can be set to TRUE afterwards) otherwise
recursion will occur.

PROCwimp_singlepollidle(seconds%)
The same as PROCwimp_pollidle, except that it is called
once and not in a loop.
If something happens then the relevant action will be taken before 
returning.
If NULL%=TRUE then PROCuser_null will be called after
seconds% seconds.
Useful for incorporating delays into multitasking loops.
Note: if calling in PROCuser_null, make sure NULL%=FALSE
before this call is made (can be set to TRUE afterwards) otherwise
recursion will occur.


3. User

FNuser_help(window%,icon%)
Return a string to be used for interactive help for the
window (and icon).
window% = handle of window (containing icon).
icon% = number of icon.

FNuser_keypress(window%,icon%,key%)
If a key is pressed while one of your windows has the input focus, or a 
hotkey is pressed, then this function is called (provided icon validation 
string is suitably defined).
If you dont use the key press then return a 0. If you do then return a 1.
window% = handle of window with input focus.
icon% = number of icon with caret.
key% = key code. For most keys it is the ASCII number.
(See Section 2.4 of the Manual for codes of special keys - and Section 
2.21 for validation strings.)

FNuser_loaddata(path$,window%,icon%,filetype$,workx%,worky%)
Used to load data. Important to return a 1 if data is loaded.
(Can also be used for other operations without loading data. In these
cases, return 0.)
path$ = full pathname of source file offered for loading.
window% = handle of window file has been dragged to. (Will be 0 if file 
double-clicked rather than dragged.)
icon% = number of icon file was dragged on to. (Will be -1 if file 
double-clicked rather than dragged.)
filetype$ = filetype of file offered for loading. Eg. FFF. (or 1000 if a 
directory, or 2000 if an application)
workx%, worky% = work area coordinates the icon was dropped at 
(these values are both -1 if file was loaded with a double-click rather 
than dragged).

FNuser_menu(window%,icon%)
If you want a menu to be displayed when you press <menu> over the
specified window/icon, then this function needs to return the handle
of the menu required - instead of the default value of 0.
window% = handle of window.
icon% = number of icon.

FNuser_menuhelp(menu%,item%)
Return a string to be used for interactive help for the
menu item.
menu% = handle of menu.
item% = number of item (starting from 1 at the top).

FNuser_pane(window%)
If the window has a pane attached to it, then this function should
return the window handle of the pane. If the window doesnt have a
pane attached, then it should return a -1.
window% = handle of window.

FNuser_printing(copy%,page%,totpages%,pagepos%)
Called repeatedly during printing so application can keep user informed 
of current printing status and give the option to cancel printing.
copy% = number of current copy being printed.
page% = number of current page being printed.
totpages% = total number of pages being printed.
pagepos% = current page being printed (starts at 1 each time and goes up 
to totpages%).
Return a 1 to cancel printing or a 0 to continue.

FNuser_quit(type%)
Called when the application is quit either from the user choosing quit or 
from a desktop shutdown.
Return a 1 to continue with the quit/shutdown or return a 0 to stop it, 
perhaps allowing the user to save any data.
If type%=0 then it is a quit.
If type%=1 then it is a shutdown.

FNuser_savedata(path$,window%)
When the user is required to save data, this function is called.
(Can also be used for file operations which do not save data, in which 
case return 0.)
Return a 1 if some data was saved, 2 if an error occurred or return a
0 for no data saved and no error.
path$ = full pathname of file to save data to i.e. destination file.
(Note that this must be a complete file path, not a directory.
Leafname is usually in save window writable icon.)
window% = handle of save window that file icon was dragged from.

FNuser_savefiletype(window%)
You return the filetype for the save windows. eg. =FFF.
For windows that arent save windows, return a null string.
window% = handle of window%

FNuser_slider(window%,icon%)
In order to let DrWimp know that an icon is part of a
slider/sliderback pair, return the slider icon number.
window% = handle of window with slider pair in.
icon% = icon number of slider back icon.
(Always used with FNuser_sliderback as a complementary pair.)

FNuser_sliderback(window%,icon%)
In order to let DrWimp know that an icon is part of a
slider/sliderback pair, return the slider back icon number.
window% = handle of window with slider pair in.
icon% = icon number of slider.
(Always used with FNuser_slider as a complementary pair.)

PROCuser_closewindow(window%)
If this function is called, then the window whose handle is window%
has just been closed.

PROCuser_declarefonts
Any fonts being used in printing must be declared in this function using 
PROCwimp_declarefont or PROCwimp_declarefonth.
(This is in case the application is used with a PostScript type
printer, which requires font declarations.)

PROCuser_enteringwindow(window%)
This function is called when the pointer enters a window.
window% = handle of window.

PROCuser_iconise(window%,RETURN text$,RETURN sprite$)
This function is called when iconising action takes place. It allows the 
text and/or sprite used to be customised.
window% = handle of the window where the iconising action has 
occurred.
text$ = text to appear beneath the iconised sprite.
sprite$ = name of the sprite to be used, without the ic_ prefix. A sprite 
with the full name needs to be supplied in the !Sprites/!Sprites22 files - 
otherwise the Wimps default sprite will be displayed.
(By default, both text$ and sprite$ will be set to the application name as 
declared in FNwimp_initialise.)
N.B. If sprite$ exceeds 7 characters it will produce an invalid iconiser 
sprite name - and hence the Wimps default iconiser sprite will be 
displayed instead.

PROCuser_initialise
This procedure should typically contain the following:
Window and menu loading/definition; declaration of global variables;
DIMming of arrays & data blocks; anything that needs to be done before 
polling starts.

PROCuser_leavingwindow(window%)
This function is called when the pointer leaves a window.
window% = handle of window.

PROCuser_menuopen(menu%,icon%)
Called just before menu (not a sub-menu) is opened.
menu% = handle of menu just about to open.
icon% = icon which pointer is over ( or -1 if not over an icon).

PROCuser_menuselection(menu%,item%)
This function is called when the user has chosen a menu item from one 
of your menus.
menu% = handle of menu.
item% = item number (top item is 1).

PROCuser_modechange
Called when the mode is changed.

PROCuser_mouseclick(window%,icon%,button%,workx%,worky%)
If an icon has been clicked on in one of your windows then this function 
is called.
window% = handle of window containing icon.
icon% = number of the icon clicked on.
button% = which mouse button was pressed.
Eg. 4 for <select>, 1 for <adjust>.
workx%,worky% = work area coordinates of pointer (in window%)
when the mouse button was clicked.

PROCuser_null
This is called continuously if you set NULL%=TRUE.
So if you are writing something like a clock, you would monitor the time 
here and change any windows as required.

PROCuser_openwindow(window%,x%,y%,stack%)
If this function is called, then the window whose handle
is window% has been opened with the top left of the
window at x%,y% on the screen.
stack% = window handle which window% was opened behind,
or -1 for top of window stack, or -2 for bottom.

PROCuser_overmenuarrow(RETURN nextsubmenu%,parentmenuitem%,x%,y%)
Called when pointer moves over arrow-head against menu item,
on way to activating sub-menu.
nextsubmenu% = handle of submenu (or could be window) about
to be opened.
(Note: RETURN means that submenu handle can be changed here, if 
required.)
parentmenuitem% = menu item number which pointer is moving over.
x%/y% are work area OS-unit positions of pointer when over
arrow-head.

PROCuser_print(minx%,miny%,maxx%,maxy%,page%)
Called to draw a page for printing, if PROCwimp_print was
called with user%=1.
minx%,miny% = coordinates of bottom left corner of clipping rectangle
on page in paper coordinates.
maxx%,maxy% = coordinates of top right corner of clipping rectangle on
page in paper coordinates.
page% = number of page to print.

PROCuser_printerchange
Called when the printer settings or the current printer has changed so you 
can update your page measurements, current printer name, etc.

PROCuser_redraw(window%,minx%,miny%,maxx%,maxy%,printing%,page%)
When this function is called, the Wimp wants you to update (redraw) the 
specified box.
The box is in the window whose handle is window% or, if printing, then 
it is in paper coordinates with the origin is at the bottom left of the paper.
printing% = TRUE if currently printing, FALSE otherwise.
page% = number of page currently being printed if printing%=TRUE.
minx%,miny% = bottom left co-ordinates of box in screen/paper 
coordinates.
maxx%,maxy% = top right co-ordinates of box in screen/paper 
coordinates.

PROCuser_saveicon(window%,RETURN drag%,RETURN write%,RETURN ok%)
This function allows the three save window icons (the one to drag, the 
writable icon for the filename/pathname and the OK button) to have
their icon numbers set, if you want to override the defaults.
Defaults:
  drag% - 0   write% - 1   ok% - 2
window% = handle of save window.

PROCuser_slidervalue(window%,slider%,pcent%,dir%)
When a slider is being dragged or has just finished being dragged, the 
percentage of the slider is passed to this function.
window% = handle of window with slider in.
icon% = icon number of slider.
pcent% = percentage of slider.
dir% = direction of slider (0 is horizontal, 1 is vertical)

PROCuser_colourpickerrgb(red%,green%,blue%,none%)
When the colour picker window is used to select a colour (by pressing 
OK or None) the rgb values of the currently displayed colour are 
passed to this function.
red% = red component of colour, in range 0-255.
green% = green component of colour, in range 0-255.
blue% = blue component of colour, in range 0-255.
If none%=0, OK was pressed in colour picker window i.e. displayed 
colour was selected.
If none%=1, None was pressed in colour picker window i.e. no colour 
selection was made.
(Note: Colour values are still passed when None is pressed.)

PROCuser_colourpickermodel(model%,value1%,value2%,value3%,value4%,none%)
When the colour picker window is used to select a colour (by pressing 
OK or None) the colour model values of the currently displayed 
colour are passed to this function.
model%=colour model number. 0 is RGB model, 1 is CMYK 
model, 2 is HSV model.
value1%, value2% etc. are colour component values appropriate to the 
model, in range 0-100% (except value1% is in range 0-359 degrees for 
HSV model i.e. when model%=2)
Note that value4% is only relevant for CMYK model i.e. when 
model%=1. In other cases value4% will be -1.
If none%=0, OK was pressed in colour picker window i.e. displayed 
colour was selected.
If none%=1, None was pressed in colour picker window i.e. no colour 
selection was made.
(Note: Colour values are still passed when None is pressed.)

PROCuser_wimpmessage(messagenumber%)
This user-function allows details of any unused wimp-messages to be 
passed to the !RunImage, if required.
If the global variable UNUSED% is set to TRUE then this PROC will be 
called whenever a wimp-message is received by the application but is 
not used within the DrWimp library. (UNUSED% is set to FALSE by 
default on application start-up.)
messagenumber% = number of the unused wimp-message received.
(See Section 2.29 of Manual for the list of wimp-messages that are 
currently used within the DrWimp library - and hence would never be 
passed on via this user-function.)


4. Windows

FNwimp_createwindow(vminx%,vminy%,vmaxx%,vmaxy%,wminx%,wminy%,wmaxx%,wmaxy%,flags%,workcol%,button%,title$,maxind%,sarea%)
Creates a window, returning the handle to it.
vminx%,vminy%,vmaxx%,vmaxy% = limits of opening visible window 
in OS screen units.
wminx%,wminy%,wmaxx%,wmaxy% = limits of work area of window
in work area OS coordinates.
flags% = number representing window flags.
workcol% = work area colour in desktop colours, in range 0-15.
button% = work area button type. 0 for ignoring clicks, 1 for responding 
to them.
title$ = title of window.
maxind% = maximum size of title if indirected.
sarea% = handle of sprite area, or 0 to use Wimp sprite area.
(See Section 2.25 of Manual for details of flags%, button%, etc.)

FNwimp_getwindowsize(window%,side%)
Returns the dimension required, in OS units, of the currently displayed 
size of the specified window. (If window is not open then size that would 
be displayed is returned.)
If side% = 0 returns width. If side% = 1 returns height.

FNwimp_getwindowtitle(window%)
Returns a string containing the window title.
window% = handle of window.

FNwimp_getwindowvisibleOS(window%,side%,end%)
Return the work area OS coordinates of the edges of the current visible 
area of the window.
window% = handle of window.
If side%=0 then a x coordinate will be returned.
If side%=1 then a y coordinate will be returned.
If end%=0, then the minimum coordinate will be returned, ie the left
or bottom of the visible area depending on the value of side%.
If end%=1, then the maximum coordinate will be returned, ie the right
or top of the visible area depending on the value of side%.

FNwimp_getwindowvisiblescreen(window%,side%,end%)
Return the screen OS coordinates of the edges of the current visible area 
of the window.
window% = handle of window.
If side%=0 then a x coordinate will be returned.
If side%=1 then a y coordinate will be returned.
If end%=0, then the minimum coordinate will be returned, ie the left
or bottom of the visible area depending on the value of side%.
If end%=1, then the maximum coordinate will be returned, ie the right
or top of the visible area depending on the value of side%.

FNwimp_getwindowworksize(window%,side%)
Returns the size, in OS units, of a window work area
window% = handle of window.
If side%=0 the width of the work area is returned.
If side%=1 the height of the work area is returned.

FNwimp_iswindowopen(window%)
Returns a 1 if the window is open otherwise returns a 0.
window% = handle of window.

FNwimp_loadwindow(path$,window$,sprite%)
Loads in a window from a templates file and returns a
handle for the window.
path$ = full pathname to templates file.
window$ = name of window in templates file.
sprite% = 0 if sprites used are from wimp pool (RMA). Otherwise 
sprite% is a handle to a user sprite area.

PROCwimp_banner(window%,delay%)
Opens window in the centre of the screen for specified
time before closing it.
window% = handle of window to open.
delay% = number of seconds to keep window on screen.

PROCwimp_closewindow(window%)
Closes a window (removes it from the screen).
window% = handle of window to close.

PROCwimp_deletewindow(window%)
Deletes a window definition, closing it if it is open. All the memory
apart from the indirected memory is reclaimed and the window handle
becomes invalid.
window% = handle of window to delete.

PROCwimp_openwindow(window%,centre%,stack%)
Opens a window on the screen.
window% = handle of window to open.
If centre% = 0 opens window where it was last left on the screen, or if it 
hasnt been opened before, then where it is positioned in the template 
file.
If centre% = 1 opens the window centred on the screen
(mode independent).
If centre% = 2 opens the window centred on the pointer.
stack% = window handle to open behind, or -1 for top of window stack, 
-2 for bottom, or -3 for current stack position.

PROCwimp_openwindowat(window%,x%,y%,stack%)
Opens a window on the screen so the top left of the
window is at co-ordinates x%,y% - in OS units.
window% = handle of window to open.
stack% = window handle to open behind, or -1 for top of window stack,
-2 for bottom or -3 for current stack position.

PROCwimp_putwindowtitle(window%,title$)
Changes the window title to title$
window% = handle of window.

PROCwimp_redrawwindow(window%)
Causes the complete window whose handle is window% to be redrawn/
updated.

PROCwimp_resizewindow(window%,width%,height%)
Resizes the work area of the specified window to the specified width and 
height, which are in OS co-ordinates.
(The displayed size of the window will not change unless the new work 
area size is less than the displayed size.)

PROCwimp_resizewindowvisible(window%,width%,height%)
Resizes the visible area of the window to the specified width and height 
which are in OS co-ordinates.

PROCwimp_scroll(window%,side%,direction%,distance%)
Causes the window to automatically scroll vertically or horizontally a 
given distance in a given direction.
window% = handle of window to be scrolled.
If side%=0 then a horizontal scroll will be done.
If side%=1 then a vertical scroll will be done.
If direction%=0 then the scroll will be left or down depending on the
value of side%.
If direction%=1 then the scroll will be right or up depending on the
value of side%.
distance% = the distance to scroll the window given in OS units.

PROCwimp_updatewindow(window%,minx%,miny%,maxx%,maxy%)
This procedure tells the Wimp to redraw only the part of a window 
which is defined by the given coordinates.
This greatly speeds up redraws where lots of graphics are used and/or the 
window needs regular updating as it avoids redrawing the whole 
window.
The necessary code needs to be in PROCuser_redraw to enable the 
redraw to be done.
window% = handle of window to be updated.
minx%, miny% = bottom left of box to be redrawn in work area
coordinates.
maxx%, maxy% = top right of box to be redrawn in work area
coordinates.


5. Messages

FNwimp_createmessagemenu(tag$,title$,size%)
Creates a menu automatically from a Messages file, with the same result 
as FNwimp_createmenu.
tag$ = tag for menu. Eg: if tag$=MMenu then the tag MMenuT will 
specify the title, MMenu1 the first item, MMenu2 the second etc.
If title$= then the title defined in the message file will be used, 
otherwise title$ will override whatever is defined in the messages file.
If size%>number of items then the menu is dynamic, ie.
the items can be increased up to size%.

FNwimp_messlook0(token$)
Returns the string in the messages file for the token token$.

FNwimp_messlook1(token$,a$)
Returns the string in the messages file for the token token$.
Any %0s in the string are replaced with a$ before returning.

FNwimp_messlook2(token$,a$,b$)
Returns the string in the messages file for the token token$.
Any %0s and %1s are replaced with a$ and b$ respectively before 
returning.

FNwimp_reinitmessages(path$)
Forgets about the current messages file and changes to a new one. The 
new file must be the same size or smaller than the old one.
Returns a 1 for success, 0 for failure.
path$ = full pathname of messages file to use.

PROCwimp_initmessages(path$)
Reserves blocks of memory and sets up Messages file for use.
path$ = full pathname of messages file to use.


6. Icons

FNwimp_createicon(window%,wminx%,wminy%,wmaxx%,wmaxy%,flags%,esg%,button%,fcol%,bcol%,font%,text$,sprite$,sarea%,maxind%,valid$)
Creates an icon and returns its handle (icon number).
window% = handle of window to create icon in.
wminx%,wminy%,wmaxx%,wmaxy% are bottom left and top
right corners of icon in work area OS coordinates.
flags% = number representing flags for icon.
esg% = esg number of icon. 0 for icons which arent radio buttons.
button% = button type of icon.
fcol%,bcol% = foreground and background colours of icons (if not using
outline font) in desktop colours, so both in the range 0-15.
font% = handle of outline font. 0 if not using a font.
text$ = text for icon.            sprite$ = sprite name for icon.
sarea% = handle of sprite area, or 0 to use Wimp sprite area.
maxind% = if icon is indirected then maximum size.
valid$ = icon validation string.
(See Section 2.25 of Manual for details of flags%, button%, etc.)

FNwimp_geticonenable(window%,icon%)
Returns a 0 if the icon icon% in the window whose handle
is window%, is disabled/greyed. Returns a 1 if it isnt.

FNwimp_geticonsize(window%,icon%,side%)
Returns the dimension required, in OS units.
window%= window handle
icon%- icon handle
If side% = 0 width of icon is returned.
If side% = 1 height of icon is returned.

FNwimp_geticonposition(window%,icon%,coord%)
Returns x/y work area OS-unit coordinates of icon corners.
window%= window handle
icon%- icon handle
If coord% = 0 minimum x coord of icon is returned.
If coord% = 1 minimum y coord of icon is returned.
If coord% = 2 maximum x coord of icon is returned.
If coord% = 3 maximum y coord of icon is returned.

FNwimp_geticonstate(window%,icon%)
Returns a 1 if the icon is selected and a 0 if it is deselected.
Useful for reading the state of radio and option icons.
window% = handle of window containing icon.
icon% = number of icon.

FNwimp_geticontext(window%,icon%)
Returns a string containing the text from the icon.
window% = handle of window containing icon.
icon% = icon number.

FNwimp_getsliderpcent(window%,icon%)
Returns the percentage of the slider. If the icon is not
a slider then 0 is returned.
The number returned is a floating point number in the
range 0-100.
window% = handle of window with slider in.
icon% = icon number of slider.

FNwimp_iconbar(sprite$,text$,maxlen%,pos%)
Creates and places an icon on the iconbar.
sprite$ = name of sprite to put on iconbar.
text$ = text to put underneath the icon.
If text$ =  then sprite-only icon will be created and maxlen% will be 
ignored.
If text$ is any other string then an indirected text-plus-sprite icon will 
be created, with space available for a maximum of maxlen% characters 
(+1). (If maxlen% is less than length of text$ then maxlen% will be 
made equal to length of text$.)
If pos% = 1 then the icon will appear on the right of iconbar.
If pos% = 0 then it will appear on the left.
Returns the iconbar window handle (-2).

PROCwimp_colouricontext(window%,icon%,colour%)
Sets colour of text in an icon to colour%.
window% = handle of window containing icon.
icon% = number of icon.
colour% = colour in range 0-15.

PROCwimp_deleteicon(window%,icon%,redraw%)
Deletes an icon definition from a window.
The icon will not disappear unless the window is redrawn.
window% = handle of window containing the icon.
icon% = icon number of icon to delete.
If redraw% is 1 then the window is redrawn.
If redraw% is 0 then it isnt and the icon wont disappear immediately.

PROCwimp_iconbarsprite(sprite$)
Changes the sprite used for the iconbar icon to sprite$.

PROCwimp_iconbit(window%,icon%,bit%,state%)
Ensures a specific bit of an icons icon flags is set to the
specified state.
window% = handle of window containing icon.
icon% = number of icon.
bit% = number of icon flags bit to change.
state% = state to set bit to. 1 to set bit, 0 to unset bit.

PROCwimp_icondisable(window%,icon%)
Greys out icon so it cannot be selected.
window% = handle of window containing icon.
icon% = number of icon.

PROCwimp_iconenable(window%,icon%)
Un-greys out icon so it can be selected.
window% = handle of window containing icon.
icon% = number of icon.

PROCwimp_iconselect(window%,icon%,state%)
Selects (inverts) and un-selects icon.
window% = handle of window containing icon.
icon% = number of icon.
If state% = 0 icon is un-selected. If state% = 1 icon
is selected.

PROCwimp_losecaret
Removes the caret from the icon it is in - and removes input focus
from the window.

PROCwimp_putcaret(window%,icon%)
Puts the caret in the icon and gives window input focus.
window% =handle of window containing icon.
icon% = number of icon (or set to -1 if caret not wanted in icon)

FNwimp_getcaretposition(choice%)
Returns information about current caret location/position.
If choice% = 0 handle of window with caret is returned.
If choice% = 1 handle of icon with caret is returned.
If choice% = 2 work area OS-unit x position (in window carrying caret) 
is returned.
If choice% = 3 work area OS-unit y position (in window carrying caret) 
is returned.
If choice% = 4 the position of the caret (the index) within the text of a 
writable icon is returned.
Return is -1 in cases where the caret is not present.

PROCwimp_puticonbartext(text$)
If the iconbar icon has indirected text underneath it then it is
replaced by text$.
(The length of text$ must not exceed the iconbars defined max. 
indirected text length.)

PROCwimp_puticontext(window%,icon%,text$)
If the icon is indirected then the text in the icon is replaced with text$.
If the icon is not indirected then an error is caused.
window% = handle of window containing icon.
icon% = number of icon.

PROCwimp_putsliderpcent(window%,icon%,pcent)
Sets the percentage of the slider. If the icon is not a
slider then this is ignored.
window% = handle of window with slider in.
icon% = icon number of slider.
pcent = percentage to set. Can be integer or floating point number,
but must be in the range 0-100.


7. Menus

FNwimp_createmenu(menu$,size%)
Creates a menu structure from the string menu$. The menu
handle is returned.
For more information on menu$ see the manual.
If size%>number of items then the menu is dynamic, ie.
the number of menu items can be increased up to size%.

FNwimp_createmenuarray(array$(),size%)
Creates a menu from the array supplied.
Each item of the menu is in a separate element of the array.
e.g. array$(1)=Info.
The first element, array$(0), is the menu title, and the last
must be the string END.
array$() = array holding item strings.
size% = maximum number of elements to allocate room for
(doesnt have to be the current number).
Returns a handle to the menu.

FNwimp_createmessagemenu(tag$,title$,size%)
Creates a menu automatically from a Messages file, with the same result 
as FNwimp_createmenu.
tag$ = tag for menu.
Eg: if tag$=MMenu then the tag MMenuT will specify the title, 
MMenu1 the first item, MMenu2 the second etc.
If title$= then the title defined in the message file will be used, 
otherwise title$ will override whatever is defined in the messages file.
If size%>number of items then the menu is dynamic, ie. the items can be 
later increased up to size%.

FNwimp_getmenuitem(menu%,menuitemtext$)
Returns the menu item number (top=1) of the menu item whose text 
matches menuitemtext$.
menu% = handle of menu to search
menuitemtext$ = text string to match
Returns 0 if no match found.

FNwimp_getmenutext(menu%,item%)
Returns a string containing the text of the menu item in position item%.
menu% = handle of menu.
item% = number of item (top item is 1).

FNwimp_getmenutitle(menu%)
Returns a string containing the title of the menu.
menu% = handle of menu.

FNwimp_menusize(menu%)
Returns the number of entries (items) in the menu.
menu% = handle of menu.

PROCwimp_attachsubmenu(menu%,item%,submenu%)
Attaches a submenu to a menu item.
menu% = handle of menu.
item% = item number (top item is 1).
submenu% = handle of submenu or window handle.

PROCwimp_menuclose
Closes the currently active menu.
Used if menu closure is required other than by normal (automatic) wimp
process.

PROCwimp_menudisable(menu%,item%)
Greys out the menu item so it is un-selectable.
menu% = handle of menu.
item% = item number (top item is 1).

PROCwimp_menudottedline(menu%,item%)
Adds a dotted line to the menu below the item.
menu% = handle of menu.
item% = number of item (top item is 1).

PROCwimp_menuenable(menu%,item%)
Un-greys out the menu item so it is selectable.
menu% = handle of menu.
item% = item number (top item is 1).

PROCwimp_menuitemcolour(menu%,item%,colour%)
Changes the text colour of the menu item specified.
menu% = handle of menu.
item% = item number (top item is 1).
colour% = colour required (standard Wimp colours in range 0-15)
(Colours 8, 10, 11, 13, 14 and 15 are best for visibility)

PROCwimp_menupopup(menu%,pos%,x%,y%)
Displays the menu (or window) whose handle is menu%.
If pos%=0 then menu is displayed at coordinates x%,y% (slightly to
right and above)
If pos%=1 then menu will be positioned as for an iconbar menu (as if
iconbar icon is at x%)
If pos%=2 then menu will be centred (x%/y% values ignored but must 
be present)
If pos%=3 then menu will be opened at the pointer position (position
optimised for ptr_menu shape)
Can also be used to open windows that close when the mouse is clicked
elsewhere.

PROCwimp_menutick(menu%,item%)
If the item doesnt have a tick next to it then this function places one.
If the item does have a tick then it is removed. i.e. toggles menu tick.
menu% = handle of menu.
item% = item number (top item is 1).

PROCwimp_menuwrite(menu%,item%,length%)
Makes the menu item writable.
menu% = handle of menu.
item% = number of item (top item is 1)
length% = maximum length of text allowed to be entered.
(Any text already in the item will be re-inserted into the new writable 
item.)

PROCwimp_putmenuitem(menu%,item%,item$)
If the menu is dynamic then item$ will be put into menu item item%.
Any items below will be shuffled down.
If item% is bigger than the current number of items+1, then it will be 
added to the bottom.
menu% = handle of menu.

PROCwimp_putmenutext(menu%,item%,text$)
Replaces menu items text with text$.
menu% = handle of menu.
item% = number of item (Top item is 1).

PROCwimp_putmenutitle(menu%,title$)
Changes the title of the menu.
More than 11 characters can be used.
menu% = handle of menu.
title$ = new title.

PROCwimp_recreatemenu(menu%,menu$)
Rebuilds the menu using the string menu$.
More items can be included than the first time as long as you dont go
over the pre-defined limit.
menu% = handle of menu to rebuild.

PROCwimp_recreatemenuarray(menu%,array$())
Rebuilds the menu using the items in the array.
The first array item (array$(0)) is the menu title, and the
last has to be the string END.
Things like ticks and dotted lines are removed.
menu% = handle of menu to rebuild
array$() = array to get items from.

PROCwimp_removemenuitem(menu%,item%)
Removes the item from the menu. Any items below are
shuffled up. If there is only one item on the menu, then
it cannot be removed.
menu% = handle of menu.
item% = number of item to remove.


8. Sprites

FNwimp_countsprites(sprite%)
Returns the number of sprites in a sprite area.
sprite% = handle of sprite area.

FNwimp_getspritename(sprite%,number%)
Returns the name of a sprite in a sprite area.
sprite% = handle of sprite area.
number% = number of sprite. First sprite is numbered 1.

FNwimp_getspritesize(sprite$,sprite%,side%)
Returns the width or height in OS units of a sprite.
sprite$ = name of sprite.
sprite% = handle of sprite area containing sprite.
If side%=0 then returns width of sprite.
If side%=1 then returns height of sprite.

FNwimp_loadsprites(path$,ptr%)
Loads a spritefile into a block of memory at ptr%.
Returns a new value of ptr% to load the next in.
path$ = full pathname to sprite file.

FNwimp_measurefile(path$)
Returns the size in bytes needed to store the spritefile.
Always use this as opposed to any other form of measurement.
path$ = full pathname of spritefile.
(N.B. Same wimp-function used for drawfiles.)

PROCwimp_rendersprite(sprite$,sprite%,bx%,by%,minx%,miny%,maxx%,maxy%,xscale,yscale)
Renders (plots) a sprite on the screen at the specified coordinates, using 
the clipping rectangle.
sprite$ = name of sprite to plot.
sprite% = handle of sprite area containing sprite.
bx%,by% = screen coordinates (OS units) at which to put bottom left
corner of sprite.
minx%,miny% = coordinates of bottom left corner of clipping rectangle
in screen coordinates (OS units).
maxx%,maxy% = coordinates of top right corner of clipping rectangle in
screen coordinates (OS units).
xscale,yscale = respectively, required scaling factors in x and y 
directions. Values <1 reduce displayed size; values >1 increase size.
(1 meaning no change in size).

PROCwimp_renderwindowsprite(window%,sprite$,sprite%,bx%,by%,minx%,miny%,maxx%,maxy%,xscale,yscale)
Renders (plots) a sprite in a window. The window must have its auto-
redraw flag unset.
window% = handle of window to render sprite in.
sprite$ = name of sprite to render.
sprite% = handle of sprite area containing sprite.
bx%,by% = work area coordinates (OS units) of where to put bottom left
of sprite.
minx%,miny% = coordinates of bottom left corner of clipping
rectangle in screen coordinates (OS units).
maxx%,maxy% = coordinates of top right corner of clipping rectangle in
screen coordinates (OS units).
(Clipping rectangle is the same as that passed to PROCuser_redraw.)
xscale,yscale = respectively, required scaling factors in x and y 
directions. Values <1 reduce displayed size; values >1 increase size.
(1 meaning no change in size).

PROCwimp_renderpoolsprite(sprite$,bx%,by%,minx%,miny%,maxx%,maxy%,xscale,yscale)
Renders (plots) a wimp pool sprite on the screen at the specified 
coordinates, using the clipping rectangle.
sprite$ = name of sprite to render (must be in the Wimp sprite pool).
bx%,by% = screen coordinates (OS units) at which to put bottom left
corner of sprite.
minx%,miny% = coordinates of bottom left corner of clipping rectangle
in screen coordinates (OS units).
maxx%,maxy% = coordinates of top right corner of clipping rectangle in
screen coordinates (OS units).
xscale,yscale = respectively, required scaling factors in x and y 
directions. Values <1 reduce displayed size; values >1 increase size.
(1 meaning no change in size).

PROCwimp_renderwindowpoolsprite(window%,sprite$,bx%,by%,minx%,miny%,maxx%,maxy%,xscale,yscale)
Renders (plots) a wimp pool sprite in a window. The window must have 
its auto-redraw flag unset.
window% = handle of window to render sprite in.
sprite$ = name of sprite to render (must be in the Wimp sprite pool).
bx%,by% = work area coordinates (OS units) of where to put bottom left
of sprite.
minx%,miny% = coordinates of bottom left corner of clipping
rectangle in screen coordinates (OS units).
maxx%,maxy% = coordinates of top right corner of clipping rectangle in
screen coordinates (OS units).
(Clipping rectangle is the same as that passed to PROCuser_redraw.)
xscale,yscale = respectively, required scaling factors in x and y 
directions. Values <1 reduce displayed size; values >1 increase size.
(1 meaning no change in size).


9. Pointer

FNwimp_getpointerposition(side%)
Returns the screen coordinates of the pointer, in OS units.
If side%=0 then the x coordinate is returned.
If side%=1 then the y coordinate is returned.

PROCwimp_bindpointer(window%)
Binds the mouse pointer within the given window in the same manner as 
a standard error message. It should be used when the window the mouse 
is to be bound in is opened.
The pointer is also placed inside the bound area if it was outside it.
Useful if your application uses its own error or message windows which 
you want to force the user to respond to.
As the pointer cannot reach any of the window control icons, your 
window should have a title bar at most.

PROCwimp_pointer(pointer%,area%,pointer$)
Changes mouse pointer between the default (number 1) and
the user defined pointer (number 2).
If pointer% = 0 default pointer is used.
If pointer% = 1 user defined pointer is used.
If area% = 0 Wimp sprite pool is used, otherwise area% is a handle to a 
sprite area.
pointer$ = sprite name of pointer.

PROCwimp_releasepointer
Releases the mouse pointer to roam over the whole screen after using 
PROCwimp_bindpointer. It should be used when the window the mouse 
is bound in is closed.

PROCwimp_setpointerposition(x%,y%)
Moves the pointer to a given position on the screen - in OS units.
x%,y% = screen coordinates to move the pointer to.


10. Drawfiles

FNwimp_getdfilesize(dfile%,side%)
Returns the dimension required - in OS units.
If side% = 0 returns width.
If side% = 1 returns height.
N.B. the returned dimensions are those of the overall bounding box 
surrounding all the drawfile objects i.e. as if all objects were grouped.

FNwimp_loaddfile(path$,ptr%)
Loads a drawfile into a block of memory at ptr%.
Returns a new value of ptr% to load the next in.
path$ = full pathname of drawfile.

FNwimp_measurefile(path$)
Returns the size in bytes needed to store the drawfile.
Always use this as opposed to any other form of measurement.
path$ = full pathname of drawfile.
(N.B. Same wimp-function used for sprites.)

PROCwimp_initdfiles
Initialises various blocks of memory ready to use with drawfiles.

PROCwimp_render(dfile%,bx%,by%,xl%,yl%,xh%,yh%,scalex,scaley,origin%)
Renders (draws) a drawfile directly to the screen using the clipping 
rectangle xl%,yl%,xh%,yh%. All coordinates are in OS units.
dfile% = handle of drawfile to render.
bx%,by% = screen coordinates of where to put bottom left corner of
drawfile.
xl%,yl% = coordinates of bottom left corner of clipping rectangle in
screen coordinates.
xh%,yh% = coordinates of top right corner of clipping rectangle in
screen coordinates.
scalex,scaley = respectively, required scaling factors in x and y 
directions. Values <1 reduce displayed size; values >1 increase size.
(1 meaning no change in size).
If origin% = 0 drawfile will be rendered with bottom left corner of 
drawfile page at bx%/by%.
If origin% = 1 drawfile will be rendered with bottom left corner of 
drawfile objects overall bounding box at bx%/by%. (See Section 2.20)

PROCwimp_renderwindow(w%,dfile%,bx%,by%,xl%,yl%,xh%,yh%,scalex,scaley,origin%)
Renders (draws) a drawfile in a window. The window must have its
auto-redraw flag unset. All coordinates are in OS units.
w% = handle of window.
dfile% = handle of drawfile to render.
bx%,by% = work area coordinates of where to put bottom left corner of 
drawfile.
xl%,yl% = coordinates of bottom left corner of clipping rectangle in 
screen coordinates.
xh%,yh% = coordinates of top right corner of clipping rectangle in 
screen coordinates.
scalex,scaley = respectively, required scaling factors in x and y 
directions. Values <1 reduce displayed size; values >1 increase size.
(1 meaning no change in size).
If origin% = 0 drawfile will be rendered with bottom left corner of 
drawfile page at bx%/by%.
If origin% = 1 drawfile will be rendered with bottom left corner of 
drawfile objects overall bounding box at bx%/by%. (See Section 2.20)

PROCwimp_savedfile(path$,dfile%)
Saves a drawfile into a file.
dfile% = handle of drawfile to save.
path$ = full pathname to save to.


11. Text

FNwimp_fontcolour(fr%,fg%,fb%)
Returns control codes in a string to change the current font colour.
Useful for using in the middle of a string of outline font text being 
plotted.
fr%,fg%,fb% = red, green and blue components respectively of the 
foreground colour, in the range 0-255.

FNwimp_fontunderline(on%)
Returns control codes in a string to turn underlining on or off.
Useful for using in the middle of a string of outline font text being 
plotted.
If on%=0 turns underlining off.
If on%=1 turns underlining on.

FNwimp_getfont(font$,size%)
Obtains a font handle for a particular font at a particular point size.
font$ = name of font, period separated. eg: Trinity.Medium.
size% = point size of font.
Returns 0 if the font cannot be found.

FNwimp_gettextsize(text$,font$,size%,side%)
Returns the size (in OS units) of a text string as if it had been plotted in a 
particular font, using a string-specified font.
text$ = string to measure.
font$ = name of font, period separated, eg: Trinity.Medium.
size% = point size of font.
If side%=0 then the plotted width (length) of the text is returned.
If side%=1 then the plotted height of the text is returned.

FNwimp_gettextsizeh(text$,font%,side%)
Returns the size (in OS units) of a text string as if it had been plotted in a 
particular font, using a font handle.
text$ = string to measure.
font% = handle of font.
If side%=0 then the plotted width (length) of the text is returned.
If side%=1 then the plotted height of the text is returned.

FNwimp_fontchangeh(font%)
Returns control codes in a string to change the current font.
Useful for using in the middle of a string of outline font text being 
plotted.
font% = handle of font to change to.

PROCwimp_deskplottext(t$,c%,x%,y%,fr%,fg%,fb%,br%,bg%,bb%)
Plots text directly to screen, using the current desktop font
(always the System Font on pre-RISC OS 3.50).
t$ = string to plot.
If c%=1 then text is horizontally centred around x%.
If c%=0 then left side of text is placed at x%.
x%,y% = screen coordinates (OS units) to plot the text at.
(y% value is bottom of text)
fr%,fg%,fb% = foreground colour red, green and blue
amounts in range 0-255.
br%,bg%,bb% = background colour red, green and blue
amounts in range 0-255.

PROCwimp_deskplotwindowtext(window%,t$,c%,x%,y%,fr%,fg%,fb%,br%,bg%,bb%,minx%,miny%,maxx%,maxy%)
Plots text in a window, using the current desktop font
(always the System Font on pre-RISC OS 3.50). 
window% = handle of window to plot in.
t$ = string to plot.
If c%=1 then text is horizontally centred around x%.
If c%=0 then left side of text is placed at x%.
x%,y% = work coordinates (OS units) to plot the text at.
(y% value is bottom of text)
fr%,fg%,fb% = foreground colour red, green and blue
amounts in range 0-255.
br%,bg%,bb% = background colour red, green and blue
amounts in range 0-255.
minx%,miny% = coordinates (OS units) of bottom left corner of clipping
rectangle in screen coordinates.
maxx%,maxy% = coordinates (OS units) of top right corner of clipping
rectangle in screen coordinates.

PROCwimp_losefont(font%)
Forgets about a font i.e. closes its handle, like closing a file.
Should be called when you have finished with the font, eg. when the
application is quitting.
font% = handle of font to lose.

PROCwimp_plottext(t$,f$,s%,x%,y%,fr%,fg%,fb%,br%,bg%,bb%)
Plots text directly to screen, using string-specified font.
t$ = string to plot.
f$ = name of font period spaced eg: Trinity.Medium
s% = point size of font.
x%,y% = screen coordinates (OS units) to plot the text at.
(y% value is bottom of text)
fr%,fg%,fb% = foreground colour red, green and blue
amounts in range 0-255.
br%,bg%,bb% = background colour red, green and blue
amounts in range 0-255.

PROCwimp_plottexth(t$,font%,x%,y%,fr%,fg%,fb%,br%,bg%,bb%)
Plots text directly to screen, using font specified by font handle.
t$ = string to plot.
font% = handle of font.
x%,y% = screen coordinates (OS units) to plot the text at.
(y% value is bottom of text)
fr%,fg%,fb% = foreground colour red, green and blue
amounts in range 0-255.
br%,bg%,bb% = background colour red, green and blue
amounts in range 0-255.

PROCwimp_plotwindowtext(window%,t$,f$,s%,x%,y%,fr%,fg%,fb%,br%,bg%,bb%,minx%,miny%,maxx%,maxy%)
Plots text in a window, using string-specified font.
window% = handle of window to plot in.
t$ = string to plot.
f$ = name of font to use, period separated, eg: Trinity.Medium.
s% = point size of font.
x%,y% = work area coordinates (OS units) to plot text at.
(y% value is bottom of text)
fr%,fg%,fb% = foreground colour red, green and blue
amounts in the range 0-255.
br%,bg%,bb% = background colour red, green and blue
amounts in the range 0-255.
minx%,miny% = coordinates (OS units) of bottom left corner of clipping
rectangle.
maxx%,maxy% = coordinates (OS units) of top right corner of clipping
rectangle.

PROCwimp_plotwindowtexth(window%,t$,font%,x%,y%,fr%,fg%,fb%,br%,bg%,bb%,minx%,miny%,maxx%,maxy%)
Plots text in a window, using font specified by font handle.
window% = handle of window to plot in.
t$ = string to plot.
font% = handle of font to use.
x%,y% = work area coordinates (OS units) to plot text at.
(y% value is bottom of text)
fr%,fg%,fb% = foreground colour red, green and blue
amounts in the range 0-255.
br%,bg%,bb% = background colour red, green and blue
amounts in the range 0-255.
minx%,miny% = coordinates (OS units) of bottom left corner of clipping
rectangle.
maxx%,maxy% = coordinates (OS units) of top right corner of clipping
rectangle.


12. Printing

FNwimp_getpapersize(side%,type%)
Returns various information about the current paper size set up in loaded 
printer driver - in OS units.
If side%=0 then a horizontal measurement is returned.
If side%=1 then a vertical measurement is returned.
Which measurement is determined by type%.
If type%=0 then the width or height is returned.
If type%=1 then the left or bottom margin is returned.
If type%=2 then the printable width or printable height is returned.
If type%=3 then the right or top margin is returned.

FNwimp_getpdrivername
If a printer driver is loaded, then this function returns a string containing 
the name of the printer driver.
Check to make sure one is loaded first with FNwimp_pdriverpresent.

FNwimp_papertoscreen(window%,coord%,side%,orient%)
Converts a paper x or y coordinate to a screen x or y coordinate - all in 
OS units.
window% = handle of window whose work area to use.
(A window reference is needed because paper values are assumed to map 
to positions in a window - from which screen coords are calculated.)
coord% = coordinate (x or y).
If side%=0 then coord% is a x coordinate, and an x coordinate is 
returned.
If side%=1 then coord% is a y coordinate, and a y coordinate is returned.
If orient%=0 then page is portrait.
If orient%=1 then page is landscape.

FNwimp_papertowork(coord%,side%,orient%)
Converts a paper x or y coordinate to a work area x or y coordinate - all 
in OS units.
(Paper values are assumed to map to positions in a window. Hence x 
values are the same and y values only referenced to different corner.)
coord% = coordinate (x or y).
If side%=0 then coord% is a x coordinate, and an x coordinate is 
returned.
If side%=1 then coord% is a y coordinate, and a y coordinate is returned.
If orient%=0 then page is portrait. If orient%=1 then page is landscape.

FNwimp_pdriverpresent
Checks to see if a printer driver is loaded.
Returns a 0 if one isnt, returns a 1 if one is.

FNwimp_screentopaper(window%,coord%,side%,orient%)
Converts a screen x or y coordinate to a paper x or y coordinate - all
in OS units.
(A window reference is needed because paper values are assumed to map 
to positions in a window.)
window% = handle of window whose work area to use.
coord% = coordinate (x or y).
If side%=0 then coord% is a x coordinate, and an x coordinate is 
returned.
If side%=1 then coord% is a y coordinate, and a y coordinate is returned.
If orient%=0 then page is portrait. If orient%=1 then page is landscape.

FNwimp_worktopaper(coord%,side%,orient%)
Converts a work area x or y coordinate to a paper x or y coordinate -
all in OS units.
(Paper values are assumed to map to positions in a window. Hence x 
values are the same and y values only referenced to different corner.)
coord% = coordinate (x or y).
If side%=0 then coord% is a x coordinate, and an x coordinate is 
returned.
If side%=1 then coord% is a y coordinate, and a y coordinate is returned.
If orient%=0 then page is portrait. If orient%=1 then page is landscape.

PROCwimp_declaredfilefonts(drawfile%)
Declares the fonts used in a drawfile (especially) for postscript printing.
drawfile% = handle of drawfile to be printed.

PROCwimp_declarefont(font$)
Declares a font for printing.
font$ = name of font to declare, period separated e.g. Trinity.Medium.

PROCwimp_declarefonth(font%)
Declares a font for printing using font handle.
font% = handle of font to declare.

PROCwimp_print(user%,window%,fpage%,lpage%,perpage%,copies%,orient%)
Initiates printing of a document.
If user%=0 PROCuser_redraw is called to draw the pages, with 
printing% set to TRUE and the clipping rectangle set to the page 
coordinates.
If user%=1 PROCuser_print is called to draw the pages.
window% = handle of window to redraw if user%=0.
fpage% = page number of first page to print.
lpage% = page number of last page to print.
perpage% = number of A4 pages to fit onto a physical A4 page. Can be
1, 2 or 4.
copies% = number of copies of the document to print.
If orient%=0 then page is portrait.
If orient%=1 then page is landscape.


13. Dynamic areas

FNwimp_changedynamic(darea%,absolute%,size%)
Changes the size of a dynamic area.
darea% = handle of dynamic area to change the size of.
If absolute%=1 then the size in bytes given in size% is the new absolute 
size of the dynamic area.
If absolute%=0 then the size in bytes given in size% is the amount to 
change the dynamic area size by. (In this case, if size% is positive then 
the area will become larger, if size% is negative then the area will 
shrink.)

FNwimp_createdynamic(size%,type%,drag%,name$)
Creates a dynamic area.
size% = size of area initially in bytes.
If type%=1 then the area is in the module area.
If type%=0 and RISC OS 3.5+ is being used then a specific dynamic 
area is created.
If type%=0 and drag%=1 then the user can change the size of the area by 
dragging in the Task Manager. (If type%=1 then drag% is ignored.)
If type%=0 then name$ is the name of the dynamic area, which appears 
in the Task Manager. (If type%=1 then name$ is ignored.)
Returns a handle for the dynamic area.

FNwimp_measuredynamic(darea%)
Returns the current size of a dynamic area in bytes.
darea% = handle of dynamic area to measure.

PROCwimp_deletedynamic(darea%)
Deletes a dynamic area, returning the memory so it can be used for other 
applications, modules, etc.
darea% = handle of dynamic area to delete


14. Colour picker

PROCwimp_opencolourpickerrgb(dialoguetype%,red%,green%,blue%,x%,y%)
Opens the colour picker window with the initial colour set by the values 
of red%, green% and blue%, which are in the range 0-255.
The window will open in the RGB model (which means the set colour
values will actually be shown as percentages in the range 0-100%).
x%/y% give the screen OS-unit coordinates of the top left corner of
the opening window.
dialoguetype% determines how the window will close:
If dialoguetype%=0 the window will be closed by specific action e.g. 
selecting its Close icon.
If dialoguetype%=1 the window will close if the mouse is clicked 
outside the window.
(Note: the window also closes when the OK or None button is 
selected.)

PROCwimp_opencolourpickermodel(model%,dialoguetype%,value1%,value2%,value3%,value4%,x%,y%)
Opens the colour picker window with the colour model set by model% 
and the initial colour set by the values of value1%, value2%, etc.
model%=0 for RGB model, 1 for CMYK model, 2 for HSV model.
value1%, value2% etc. are in range 0-100%, except that value1% is
in the range 0-359 degrees (the colour angle in HSV) when model%=2.
value4%, which must always be present, is ignored unless model%=1 
(CMYK model).
x%/y% are screen OS-unit coordinates of top left corner of window.
If dialoguetype%=0 the window will be closed by specific action e.g. 
selecting its Close icon.
If dialoguetype%=1 the window will close if the mouse is clicked 
outside the window.
(Note: the window also closes when OK or None button is selected.)

PROCwimp_opensubmenucolourpickerrgb(red%,green%,blue%, x%,y%)
Opens the colour picker window as a sub-menu, with the initial colour 
set by the values of red%, green% and blue%,
which are in the range 0-255.
The window will open in the RGB model (which means the set colour
values will actually be shown as percentages in the range 0-100%).
x%/y% give the screen OS-unit coordinates of the top left corner of
the opening window.
As with any sub-menu, the window will close if the mouse is clicked 
outside the window or when the mouse pointer retraces the opening 
route. (Note: the window also closes when the OK or None button is 
selected.)

PROCwimp_opensubmenucolourpickermodel(model%,value1%,value2%,value3%,value4%,x%,y%)
Opens the colour picker window as a sub-menu, with the colour 
model set by model% and the initial colour set by the values of 
value1%, value2%, etc.
model%=0 for RGB model, 1 for CMYK model, 2 for HSV model.
value1%, value2% etc. are in range 0-100%, except that value1% is
in the range 0-359 degrees (the colour angle in HSV) when model%=2.
value4%, which must always be present, is ignored unless model%=1 
(CMYK model).
x%/y% are screen OS-unit coordinates of top left corner of window.
As with any sub-menu, the window will close if the mouse is clicked 
outside the window or when the mouse pointer retraces the opening 
route. (Note: the window also closes when the OK or None button is 
selected.)
