home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 3 / PDCD_3.iso / utilities / utilsd / drwimp / TextManual < prev   
Text File  |  1995-05-29  |  82KB  |  2,092 lines

  1.  
  2.              -------------------------------------------------
  3.                                   DrWimp
  4.  
  5.                        Cures your desktop problems!
  6.  
  7.  
  8.  
  9.                              1.05 (28-May-95)
  10.  
  11.                             © Andrew Ayre 1995
  12.  
  13.                    Public Domain - see conditions of use      
  14.              -------------------------------------------------
  15.  
  16.  
  17. *****************************************************************************
  18. Section 1 - Introduction
  19. *****************************************************************************
  20.  
  21. Prologue
  22.  
  23.   Ever wanted to write high quality multitasking programs? Can't quite get
  24. the hang of manipulating words, bytes, menu structures and message systems?
  25. Have you looked in despair at the amount of programming needed to get a
  26. single window on the desktop?
  27.  
  28.   Forget all your worries and write great applications with great ease;
  29. Doctor Wimp is here!
  30.  
  31. DrWimp - solves all your multitasking worries!
  32.  
  33.   Banish that dodgy polling code to your disc box! Wipe that broken window
  34. redraw program from your hard drive! Drop that tired out menu creator into
  35. your null: device!!
  36.  
  37.   The DrWimp system consists of:
  38.  
  39.   •The DrWimp library.
  40.   •A template !RunImage file.
  41.   •This manual in Impression format and text format.
  42.   •Example Template files for standard windows.
  43.   •Support files for the tutorials.
  44.   •!Func'n'Proc quick browser.
  45.   •!MakeApp2, !Crunch and !TemplEd PD utilities.
  46.   •Example applications written using DrWimp, with fully commented code.
  47.  
  48. DrWimp - THE system to use!
  49.  
  50. Conditions of use
  51.  
  52.   DrWimp may be distributed for free and without the documentation,
  53. examples, utilities, etc. if it is being used in a Public Domain, Shareware,
  54. Cover Disc or Disc Magazine program. If you wish to distribute it with a
  55. commercial program then contact the author to obtain permission and
  56. negotiate royalties.
  57.  
  58.   Public Domain libraries may charge for materials, handling, etc. as long
  59. as this does no exceed £2.00 (UK) net.
  60.  
  61.   The DrWimp file may not be reproduced in part. It may only be reproduced
  62. in whole. I recommend using !MakeApp2 and !Crunch for security.
  63.  
  64.   The DrWimp system (apart from !MakeApp2, !Crunch and !TemplEd) may only be
  65. distributed as a whole. For conditions of use of !MakeApp2, !Crunch and
  66. !TemplEd see their own !Help files.
  67.  
  68.   The author retains copyright of DrWimp, documentation and examples at all
  69. times.
  70.  
  71.   Documentation and utilities can be obtained from the Datafile PD library
  72. or direct from the author at:
  73.   E-mail:   A.J.Ayre@e-eng.hull.ac.uk
  74.  
  75.   Help on any aspect of DrWimp (and the documentation + utils if you include
  76. a DD disc) can be obtained from the author at:
  77.  
  78.   Snail mail:  Andrew Ayre
  79.     24 Skirbeck Rd,
  80.     Gillshill Rd,
  81.     Hull,
  82.     East Yorkshire
  83.     HU8 0HR
  84.     England
  85.   E-mail:  A.J.Ayre@e-eng.hull.ac.uk
  86.  
  87. Getting started
  88.  
  89.   In this manual all functions (FN) and procedures (PROC) will be referred
  90. to as just functions.
  91.  
  92.   The file DrWimp does all the work, and the !RunImage file is where you
  93. control things from.
  94.   DrWimp is just a collection of functions that you can call from the
  95. !RunImage file. All the functions in DrWimp are in lowercase and preceded by
  96. “wimp_”, eg:
  97.  
  98. PROCwimp_dosomethingamazing(curtain$)
  99.  
  100.   Some of these functions need help from you, so they call a function that
  101. is in the !RunImage file, where you can easily tailor it to your
  102. applications needs. All these functions are also in lowercase, but they are
  103. preceded by “user_”, eg:
  104.  
  105. FNuser_givemesomehelp(tomato$)
  106.  
  107.   For a “blank” application which does nothing all the “user_” functions
  108. will be empty, and return default values if they are of the “FN” type. These
  109. functions have to be there otherwise your application might complain that
  110. one of them can't be found, regardless of whether they do anything or not.
  111.  
  112.   From now on functions in the !RunImage file preceded by “user_” will be
  113. referred to as “user functions”, and functions in the DrWimp file preceded
  114. by “wimp_” will be referred to as “wimp functions”.
  115.  
  116.   To save you having to type in a standard set of user functions every time
  117. you write an application, there is a template application called “!MyApp”.
  118. Inside !MyApp is a template !RunImage file. This file calls a function that
  119. starts up your application, because you can't do anything multitasking until
  120. you call it. You will have to change the details of this call to suit your
  121. application.
  122.  
  123.   The utility !Fnc'n'Prc (supplied in the “Utils” folder) is a catalogue of
  124. all the user and wimp functions. It details what parameters you have to pass
  125. and what is returned. It is also a demonstration of the DrWimp system, as it
  126. was written using it, and in particular the ability to easily add panes to
  127. windows and saving files.
  128.   The source code is included, and is fully commented to help you further
  129. understand how to get DrWimp to do what you want.
  130.   It may seem that most of the functions have far too many parameters than
  131. is needed. This is true in that most of the time the parameters will be
  132. largely the same, but having more parameters gives you, the programmer, as
  133. much flexibilty as possible.
  134.  
  135.   The main difference that multi-tasking programs have over the others, is
  136. that they are not linear. The program doesn't start at the top and work its
  137. way to the bottom. Instead, multi-tasking programs jump about depending on
  138. whether an icon has been clicked on, or a window dragged, or a menu item
  139. chosen, etc. All your application has to do is respond to these “events”
  140. when they happen.
  141.  
  142. Handles
  143.  
  144.   DrWimp expects windows to be loaded in from a templates file. Menus are
  145. created from a shorthand in the !RunImage file. Once you have loaded in a
  146. window or created a menu you need some way of getting at the information so
  147. you can put the menu on the screen, or change some of the window attributes,
  148. etc. The way this is done is by handles, and they form a very important part
  149. in programming the wimp.
  150.  
  151.   When you load in a window, DrWimp asks the machine to reserve some memory
  152. for it to put all the information about the window into. It does this using
  153. the DIM command, eg:
  154.  
  155. DIM block% 256
  156.  
  157.   This will reserve a chunk of memory 256 bytes long, and the first memory
  158. address in that chunk is in block%. This is so you can find it and change
  159. the contents of the chunk of memory.
  160.   So if you load in a window called “save”, then you might reserve a chunk
  161. of memory called save%, so you can easily see that the memory address save%
  162. is the start of the information about the save window, you loaded in when
  163. the application first started.
  164.   The handle to the save window is therefore save%.
  165.  
  166.   The same is for menus. When you ask DrWimp to create a menu from the
  167. shorthand that you supply, it gets a chunk of memory and fills it with the
  168. information needed for the wimp to create the menu. eg: if you were creating
  169. a menu for the iconbar icon of your application, then you might call the
  170. handle something like barmenu%.
  171.  
  172.   In general it is very wise to call the handle something that reminds you
  173. of what it is a handle for. If you load in five windows, then it would be a
  174. bit stupid to call the handles a%, b%, c%, d%, e%!
  175.  
  176.   You will find that most wimp and user functions require a handle to a
  177. window or a menu to be passed to them, so you will need to use them a lot.
  178.  
  179.   Look at the following piece of code (the functions will be described in
  180. more detail later on):
  181.  
  182. find% = FNwimp_loadwindow("Templates","find",1)
  183. PROCwimp_openwindow(find%,1,-1)
  184.  
  185.   The first line calls a wimp function that loads in a window from a
  186. templates file called “find”, so we can assume that it is a window for
  187. entering something to find. The function returns a handle to the window,
  188. which has been called find%. From now on, whenever we want to do something
  189. with the find window, we use the variable find%. Look at the second line.
  190. Here a wimp function is being called that opens a window. Passed to it is
  191. the window handle, telling it which window to open (and some numbers
  192. regarding the positions to open it at).
  193.  
  194.   The handle could have been called anything, eg:
  195.  
  196. coffee% = FNwimp_loadwindow("Templates","find",1)
  197.  
  198.   Or changed later on, eg:
  199.  
  200. find% = FNwimp_loadwindow("Templates","find",1)
  201. coffee% = find%
  202.  
  203. Variables & Strings
  204.  
  205.   One of the first lines of the !RunImage file should be something like:
  206.  
  207. LIBRARY "<MyApp$Dir>.DrWimp"
  208.  
  209.   This tells the BASIC interpreter that you want to use a library and where
  210. it is. After this call, the two files (DrWimp and !RunImage) may be separate
  211. but they work as if all the code is in one file. Eg: you can call functions
  212. in DrWimp from !RunImage and call functions in !RunImage from DrWimp.
  213.   More importantly, any variables or strings that are created in one of the
  214. files and isn't localised, will be available to both files, so either one
  215. can alter the contents. This can cause problems, because you could be using
  216. a variable in the !RunImage file, and then call a wimp function that also
  217. uses it, so when the function is exited, the variable will be different from
  218. what your code expects.
  219.   This problem has been largely overcome by localising most of the variables
  220. used in DrWimp. However, there are a handful of variables that cannot be
  221. localised for one reason or another.
  222.  
  223.   All but two of the variables start with a lowercase “w”, so you can easily
  224. choose variable names that don't clash: simply don't start them with a “w”.
  225.   The variables that start with “w” should not be changed. The two other
  226. variables finished% and NULL are supposed to be changed:
  227.  
  228.   By setting finished% to TRUE, the application will quit as soon as
  229. possible. This is how the Quit menu option on the iconbar menu works.
  230.   By setting NULL to TRUE, the user function PROCuser_null will be called
  231. every time the wimp passes control to the application and nothing is
  232. happening with it, eg: clicking on icons, dragging windows, receiving
  233. messages, etc. This is useful for timed or delayed things. You keep track of
  234. the time and after a certain delay you change a windows contents (say for a
  235. clock) or send a message to another application.
  236.  
  237. System variables
  238.  
  239.   It is important that you make sure that your application can run from
  240. anywhere, eg: floppy disc, hard drive, CD, etc, but you have to access files
  241. in the application directory, eg: templates, sprites, message files, etc.
  242.  
  243.   System variables differ from BASIC variables in that System variables are
  244. set from the command line using a star command. Unfortunately it isn't very
  245. easy to read the contents of a system variable from BASIC programs. Because
  246. of this, DrWimp provides a wimp function (FNwimp_sysvariable) to do this for
  247. you, and it will be described in more detail later.
  248.  
  249.   When the !Run file of your application is run it sets up a system variable
  250. called “Obey$Dir” which contains the full pathname to your application
  251. directory. So if you have a file called “Templates” inside your application
  252. directory, then its full pathname can be written as <Obey$Dir>.Templates.
  253.   But if between your !Run file being run and your application loading in a
  254. file, another !Run file from another application is run, Obey$Dir will
  255. change. So in your !Run file you must make a copy of Obey$Dir that can be
  256. used instead.
  257.   If your application is called “MyApp” then you would use:
  258.  
  259. Set MyApp$Dir <Obey$Dir>
  260.  
  261. and then you would get to your “Templates” file inside your application
  262. directory by using: <MyApp$Dir>.Templates.
  263.  
  264.   System variables can also be used for other things. Eg: if you wrote a
  265. database application then you might have to set the maximum number of
  266. records allowed for the amount of memory that you have allocated. The limit
  267. could be put in the !Run file instead of the !RunImage file so
  268. non-programmers don't have to go and delve into your code. So you could have
  269. a line in your !Run file like:
  270.  
  271. Set MaxRecords 5000
  272.  
  273. Then in your !RunImage file you could read the value with something like:
  274.  
  275. MaxAllowed% = VAL(FNwimp_sysvariable("MaxRecords"))
  276.  
  277. Security
  278.  
  279.   If you are going to distribute a new and brilliant application that you
  280. have slaved over for weeks, then you are going to want some security.
  281.  
  282.   !MakeApp2 and !Crunch between them re-filetype and completely mangle BASIC
  283. programs up, and they still run. If you have a !RunImage file and a library
  284. which it uses then you can't mangle the library, only the !RunImage file.
  285. But what you can do is add the library onto the end of your !RunImage file.
  286.   !MakeApp2 and !Crunch have their own !Help files, but here is a brief
  287. summary:
  288.  
  289.   •First of all make a copy of your !RunImage file!!
  290.   •Add DrWimp onto the end of your !RunImage file (this can be done easily
  291. in !Edit by positioning the caret at the end of !RunImage then dragging
  292. DrWimp into the window)
  293.   •Remove the LIBRARY command.
  294.   •Resave as !RunImage.
  295.   •Load !MakeApp2 and !Crunch and drop !RunImage on !MakeApp2 and save as
  296. something like “Absolute” (it should be filetyped as Absolute now).
  297.   •Drag the absolute file onto !Crunch and when it has finished save as
  298. !RunImage. You should get something like 50% compression.
  299.  
  300.   Make sure that you are running the !RunImage file from !Run with something
  301. like:
  302.  
  303. Run <Obey$Dir>.!RunImage
  304.  
  305. and not:
  306.  
  307. BASIC -quit <Obey$Dir>.!RunImage
  308.  
  309.   If you have an Info window in your application then don't put your name
  310. into the icon in the templates file. Instead put it in using
  311. PROCwimp_puticontext from the !RunImage file.
  312.  
  313.  
  314. *****************************************************************************
  315. Section 2 - Tutorials
  316. *****************************************************************************
  317.  
  318. Notes
  319.  
  320.   This is the bit where you get to do some programming at last!, but first
  321. some quick notes.
  322.  
  323.   I would highly recommend using !TemplEd for editing/creating template
  324. files. It is very easy to use and it is included with DrWimp. Full
  325. instructions can be found in Manual inside the !TemplEd directory.
  326.  
  327.   The tutorials use some support files and pre-made templates files. They
  328. can be found inside the Tutorial directory. They template files contain
  329. standard windows like Info and Save windows. Feel free to use these in your
  330. programs (PD or commercial). There are no conditions attached to them.
  331.  
  332.   Before you start, make a copy of the “blank” application !MyApp to work
  333. on. Put it on a fresh disc or in a new directory.
  334.  
  335.   If you get stuck or come across a problem then please, don't hesitate to
  336. get in touch. Your information could benefit other users.
  337.  
  338.   Most learning is done through experimentation. In most of the tutorials,
  339. you will be invited to fiddle and generally muck about with the code. The
  340. worst that can happen through doing this is your application crashes and is
  341. quitted by the Task Manager.
  342.  
  343.   To help you to understand further how to use DrWimp, some applications are
  344. supplied with the DrWimp system. They have fully commented !RunImage files
  345. so you can study them.
  346.  
  347.   •!Fnc'n'Prc lists summaries of all the functions related to DrWimp. It
  348. demonstrates: panes, interactive help, save windows/saving data.
  349.   •!FontRun is a utility to choose whether to boot your fonts or not
  350. whenever you reset your machine. There are two versions of this. One is a
  351. Public Domain utility with the source code mangled, and the one here may
  352. only be distributed with the DrWimp system. It demonstrates: dynamic menus,
  353. drop boxes, saving data, loading data (getting pathnames of font folders).
  354.   •!Saver doesn't do anything useful. It just demonstrates a multi-filetype
  355. save window.
  356.   •!Bar also doesn't do anything useful. It demonstrates how to use bars.
  357. They can be useful for show the percentage done of an operation, etc.
  358.  
  359. 1. Getting going
  360.  
  361.   Double-click on !MyApp. Nothing should happen. If you now open the task
  362. manager display and look at the list of tasks, you should see “MyApp” at the
  363. bottom.
  364.  
  365.   Load !RunImage into !Edit and take a look at how it works. The !Run file
  366. copies the system variable Obey$Dir into MyApp$Dir. The LIBRARY command can
  367. then be used with the system variable.
  368.   The application name is put into a string to make it easier to change
  369. later on. The next line is in case of an error. All it does is call
  370. PROCwimp_error. This wimp function will be looked at in more detail later
  371. on.
  372.   The next line is very important and your application can't do anything
  373. until it has been called. It registers your application with the task
  374. manager and it returns a handle for your task. This has been put into task%.
  375.   For the moment the second and third parameters are just set to largish
  376. values. When the application is finished you can reduce them. Basically they
  377. are (from left to right) sizes of areas to reserve for window definitions
  378. (including all the icons in the window), and the indirected text (like large
  379. menu entries and long window titles). The first parameter is the text that
  380. appears in the task manager window, and can be anything. Try it and see!
  381. Note: the wimp automatically truncates it if it is too long. The last
  382. parameter is the minimum version number of RISC OS that the application is
  383. allowed to run on multiplied by 100. The default is 200, so MyApp will run
  384. on RISC OS 2.00 or better. Note: the version number returned by the WIMP to
  385. DrWimp isn't always very accurate. For example, if you want to set the
  386. minimum version to RISC OS 3.11, then set the last parameter to 316! This is
  387. not the fault of DrWimp.
  388.   The final line calls PROCwimp_poll. This is a continuous loop until your
  389. application quits for some reason, and makes it multitasking.
  390.   The rest of the !RunImage file is all the user functions. They are all
  391. empty at the moment and do nothing or return default values.
  392.  
  393.   It doesn't do much at the moment and there is nowhere for the user to get
  394. access to our application. The best thing to do is add an icon to the
  395. iconbar.
  396.   After FNwimp_initialise, add the following line:
  397.  
  398. ibar%=FNwimp_iconbar("!myapp","",1)
  399.  
  400.   The function returns a handle to the window that contains the icon.
  401. “!myapp” is the name of the sprite to use for the icon. Try changing it to
  402. “!draw” and see what happens. The next parameter is the text to place under
  403. the icon (like the floppy drive icon). If it is an empty string then no text
  404. is printed. Try entering some text and reload the application. The final
  405. parameter controls the side of the iconbar that the icon appears on. 0 for
  406. left and 1 for right.
  407.  
  408. 2. Menus
  409.  
  410.   What is needed now is a menu for the iconbar. Menus are created by DrWimp
  411. from a shorthand form which is passed as a string. DrWimp translates it into
  412. the correct layout in a block of memory for the wimp to understand. After
  413. the FNwimp_iconbar, add the following line:
  414.  
  415. barmenu%=FNwimp_createmenu("MyApp/Info/Quit",0)
  416.  
  417.   This creates a menu and returns a handle for it, which is put into
  418. barmenu%. Each entry or item on the menu is separated by a “/”. The first
  419. item is the menu title, so from the line just added, a menu will be created
  420. with the title “MyApp” and two entries. The top one is “Info” and the bottom
  421. one is “Quit”. The last parameter is the maximum number of items allowed to
  422. be used. It is set to 0, so this means that just allow space for the items
  423. specified.
  424.  
  425.   At the moment DrWimp doesn't know about the menu, all we have done is set
  426. it up in memory. Whenever the Menu button is pressed over a window belonging
  427. to the application, DrWimp calls the user function FNuser_menu. Passed to it
  428. is the window handle (in window%) and the icon number (in icon%). If there
  429. is a menu for that window/icon then we have to return the handle to it,
  430. otherwise return a 0.
  431.   Move down to FNuser_menu and change it so it is like:
  432.  
  433. DEF FNuser_menu(window%,icon%)
  434. CASE window% OF
  435. WHEN ibar% : =barmenu%
  436. ENDCASE
  437. =0
  438.  
  439.   As you can see, whenever the window whose handle is ibar% (the window
  440. containing the iconbar icon) has menu pressed over it, the handle to the
  441. iconbar menu is returned. Try running the application.
  442.   As you will see from running it, Quit doesn't do anything. When a menu
  443. item is selected, DrWimp calls another user function:
  444. PROCuser_menuselection. This time nothing has to be returned, you only have
  445. to act on the selection made by the user.
  446.   Passed to the function is the handle of the menu that the user chose an
  447. item from (menu%) and the number of the item (item%). The top-most item is
  448. number 1, so for Quit:
  449.  
  450.   menu% = barmenu% and item% = 2.
  451.  
  452.   Add the following to make PROCuser_menuselection look like:
  453.  
  454. DEF PROCuser_menuselection(menu%,item%)
  455. CASE menu% OF
  456. WHEN barmenu% :
  457.   CASE item% OF
  458.   WHEN 2 : finished%=TRUE
  459.   ENDCASE
  460. ENDCASE
  461. ENDPROC
  462.  
  463.   Recall from Section 1, setting finished% to TRUE quits the application as
  464. soon as possible. Run the application and confirm that it does indeed work.
  465.  
  466.   Try adding some more items to the menu. Don't forget to increase the “2”
  467. in PROCwimp_menuselection accordingly though! Try getting the computer to
  468. make a beep when you select one of the items. VDU7 would be ideal for this.
  469. Note: there is no need to change the last parameter to PROCwimp_createmenu.
  470.  
  471. 3. Windows
  472.  
  473.   What is needed now is an info window that can be accessed from the iconbar
  474. menu. In the tutorials folder you will find the file “Template1”. Copy this
  475. into the MyApp application directory and rename as “Templates”. You can
  476. examine it if you want by loading it into !TemplEd.
  477.   Add the following line below FNwimp_iconbar (above FNwimp_createmenu):
  478.  
  479. info%=FNwimp_loadwindow("<MyApp$Dir>.Templates","info",1)
  480.  
  481.   This function loads in a window from the templates file, whose full
  482. pathname is given in the first parameter. The second parameter is the name
  483. of the window in the templates file, and the last parameter tells DrWimp
  484. where to get the sprites from for the window. A 0 means use a user sprite
  485. area, but we haven't set one up yet, and besides there are no sprites in the
  486. window, only the borders built into RISC OS 3. A 1 means use the wimp sprite
  487. pool (RMA), and this is the most common option.
  488.   The function returns a handle to the window which we have put into info%.
  489.  
  490.   Now we need to modify the iconbar menu to take into account the window.
  491. This is very simple to do and it is mostly done automatically. All you have
  492. to do is change the line that calls FNwimp_createmenu to look like:
  493.  
  494. barmenu%=FNwimp_createmenu("MyApp/Info>info%/Quit",0)
  495.  
  496. And thats it! Re-load MyApp and you will now see that the Info menu item now
  497. has a submenu which leads to the info window.
  498.   Looking more closely at FNwimp_createmenu: the item for the Info entry has
  499. been changed from “/Info/” to “/Info>info%/”. The “>” symbol points to a
  500. submenu for the item. All it does is tell the wimp where it can find the
  501. information to create the submenu. In this case it is a block of memory that
  502. contains the data about the info window (in other words the window handle).
  503.  
  504.   You will see in the info window that the Author and Version fields don't
  505. have the correct information in them. This is very simple to fix, and the
  506. same technique that I am about to describe can be used for any icon that has
  507. text, whether it is a Radio button, a default action button, or just a
  508. comment.
  509.  
  510.   First of all the Author field. This is icon number three. You can find the
  511. icon number by loading the Templates file into !TemplEd, opening the info
  512. window and moving the pointer over the icon. The small window at the top
  513. left will give you the icon number. Add the following line just before
  514. PROCwimp_poll:
  515.  
  516. PROCwimp_puticontext(info%,3,"© Joe Bloggs 1995")
  517.  
  518.   Replace “Joe Bloggs” with your own name (there is a limit on the length of
  519. the string though. This is fixed by the indirected size and the physical
  520. size of the box. These can easily be changed using !TemplEd.
  521.  
  522.   Now for the Version field. It is common practice to display the version
  523. number and date in the form “X.XX (Dt-Mth-Yr)”, eg:
  524.  
  525.   1.42 (16-Oct-99)
  526.  
  527.   So all you need to do is add the following line just above PROCwimp_poll
  528. (change the date, month and year to today):
  529.  
  530. PROCwimp_puticontext(info%,4,"1.00 (29-Mar-95)")
  531.  
  532.   The parameters to the function are quite simply. From left to right they
  533. are: the window handle, the icon number, and the text to put into the icon
  534. (in the window).
  535.  
  536.   Check the application works as it is supposed to and then try using the
  537. same method to change the “Purpose” field to something more interesting!
  538.  
  539. 4. Window & icon control
  540.  
  541.   Most applications have a window that appears when the user clicks on the
  542. iconbar icon. This is very easy to do:
  543.  
  544.   Copy “Template2” from the tutorial folder into the MyApp application
  545. directory, and rename as “Templates” thus overwriting the previous one. Add
  546. the following line below FNwimp_loadwindow to load in a second window:
  547.  
  548. main%=FNwimp_loadwindow("<MyApp$Dir>.Templates","main",1)
  549.  
  550.   Whenever a mouse button is pressed over one of MyApp's windows or icons,
  551. the user function PROCuser_mouseclick is called, passing to it the window
  552. handle, the icon number, and a number relating to the mouse button pressed.
  553. These are in window%, icon% and button% respectively.
  554.  
  555.   Change PROCuser_mouseclick so it looks like:
  556.  
  557. DEF PROCuser_mouseclick(window%,icon%,button%)
  558. CASE window% OF
  559. WHEN ibar% : PROCwimp_openwindow(main%,1,-1)
  560. ENDCASE
  561. ENDPROC
  562.  
  563.   As you can see, when a mouse button is pressed over the iconbar icon, then
  564. PROCwimp_openwindow is called. The first parameter is the handle of the
  565. window to open. The second means open the window in the centre of the
  566. screen, and the third parameter means open it on top of all other windows.
  567.   If the second parameter was 0 then the window would open where you last
  568. left it (ie. before it was closed), or if it was being opened for the first
  569. time then it would open as it was positioned in the templates file.
  570.   If the second parameter was -2 then the window would open behind all the
  571. others. If is was a window handle then it would open behind that window.
  572.  
  573.   Run !MyApp and check that it works, then try changing the parameters to
  574. PROCwimp_openwindow and see what happens.
  575.  
  576.   The window is divided up into three sections. I will use each section to
  577. demonstrate one or more aspects of icon control using DrWimp. The icon
  578. number for each icon can be found by loading the templates file into
  579. !TemplEd as described before.
  580.  
  581.   The first section contains a writable icon which can take up to 19
  582. characters. This amount is set by using !TemplEd and changing the indirected
  583. icon size for the writable icon.
  584.   Entering text into writable icons is fully automated by the wimp. Click in
  585. the icon and the caret will appear so you can enter some text.
  586.   What we want to do is enter some text and when Return is pressed, or 'OK'
  587. is clicked on, the text is read from the icon and copied into the text icon
  588. below.
  589.  
  590.   The wimp function FNwimp_geticontext reads text from icons. ie. it is the
  591. dual of PROCwimp_puticontext. The parameters passed are the window handle
  592. and the icon number. The function returns the text in a string. All that we
  593. need to do then is use PROCwimp_puticontext to put the text into the other
  594. icon.
  595.   Alter PROCuser_mouseclick so it looks like:
  596.  
  597. DEF PROCuser_mouseclick(window%,icon%,button%)
  598. CASE window% OF
  599. WHEN ibar% : PROCwimp_openwindow(main%,1,-1)
  600. WHEN main% :
  601. CASE icon% OF
  602. WHEN 2 : 
  603. text$=FNwimp_geticontext(main%,1)
  604. PROCwimp_puticontext(main%,11,text$)
  605. ENDCASE
  606. ENDCASE
  607. ENDPROC
  608.  
  609.   Re-load !MyApp and check that it works. You should be able to see from the
  610. code above that the writable icon is number 1 and the text icon is number
  611. 11.
  612.   Now we have to get the Return key to perform the same action when it is
  613. pressed and the caret is in the writable icon. Pressing the return key in
  614. this situation should always act the same as clicking on the icon with the
  615. yellow trough/border around it.
  616.  
  617.   FNuser_keypress is called whenever a key is pressed. Passed to it is the
  618. window handle and the icon number to locate the caret. Also passed to it is
  619. the ASCII number of the key, which for Return is 13. If we use the keypress
  620. to do something then we must return a 1. This is to stop the keypress being
  621. passed onto other tasks.
  622.  
  623.   Alter FNuser_keypress so it is like:
  624.  
  625. DEF FNuser_keypress(window%,icon%,key)
  626. used=0
  627. CASE window% OF
  628. WHEN main% :
  629. CASE icon% OF
  630. WHEN 1 :
  631. IF key=13 THEN
  632. text$=FNwimp_geticontext(main%,1)
  633. PROCwimp_puticontext(main%,11,text$)
  634. used=1
  635. ENDIF
  636. ENDCASE
  637. ENDCASE
  638. =used
  639.  
  640.   There is a lot of code there for what it actually does, but it has be
  641. written so it is easy to add more pieces of code for lots of windows and
  642. icons, with the minimum amount of effort. Also it allows the code to be
  643. executed to be put onto several lines, making easier to read.
  644.  
  645.   There is just one thing missing now. When you click on the 'OK' icon it
  646. presses in briefly. When you press Return it doesn't. It is much more
  647. reassuring for the user to see it press in, because then they know exactly
  648. what has happened, and that they haven't just wipe half their document or
  649. any other unsaved data away.
  650.   DrWimp provides a wimp function to invert or select an icon, and un-select
  651. it again, so all we have to do is select the 'OK' icon, copy the text, then
  652. un-select the 'OK' icon.
  653.  
  654.   Alter the part between “IF key=13 THEN” and “ENDIF” so it looks like:
  655.  
  656. IF key=13 THEN
  657. PROCwimp_iconselect(main%,2,1)
  658. text$=FNwimp_geticontext(main%,1)
  659. PROCwimp_puticontext(main%,11,text$)
  660. used=1
  661. PROCwimp_iconselect(main%,2,0)
  662. ENDIF
  663.  
  664.   Re-run !MyApp and check it works. PROCwimp_iconselect has three
  665. parameters. The first is the window handle and the second is the icon
  666. number. In this case it is 2 for the 'OK' icon. The last parameter controls
  667. the inversion/selection. If it is a 1 then the icon is selected, a 0 makes
  668. it unselected. If you removed the second PROCwimp_iconselect then the 'OK'
  669. button would stay pressed in. Try it and see!
  670.  
  671.   The second section contains two radio buttons and an button labelled
  672. 'Swap'. Both the radio buttons have the same ESG group (out of an ESG group,
  673. only one radio button can be selected at once(see !TemplEd)), so clicking on
  674. one de-selects the other. What I want to do is get it so when the user
  675. clicks on 'Swap' the selected and de-selected radio icons swap over, as if
  676. you had clicked on the de-selected one. The button has an icon number of 6.
  677.   If you write an application with radio buttons, you have to keep track of
  678. which ones are selected. For MyApp we will use choice% which will be either
  679. 1 or 2 depending on which one is selected. When you first load MyApp, Choice
  680. 1 is selected (you have to do this when editing the template), so we will
  681. set choice% to 1 at the start. When 'Swap' is clicked on, we look at choice%
  682. to decide which to select and which to de-select.
  683.  
  684.   Just before PROCwimp_poll, add the following line:
  685.  
  686. choice%=1
  687.  
  688.   After PROCwimp_puticontext(main%,11,text$) in PROCuser_mouseclick, before
  689. the ENDCASE, add the following:
  690.  
  691. WHEN 6 :
  692. IF choice%=1 THEN
  693. PROCwimp_iconselect(main%,4,0)
  694. PROCwimp_iconselect(main%,5,1)
  695. ENDIF
  696. IF choice%=2 THEN
  697. PROCwimp_iconselect(main%,4,1)
  698. PROCwimp_iconselect(main%,5,0)
  699. ENDIF
  700. choice%=ABS(1-(choice%-2))
  701. WHEN 4 :
  702. choice%=1
  703. WHEN 5 :
  704. choice%=2
  705.  
  706.   It is mostly self explanatory. “choice%=ABS(1-(choice%-2))” toggles
  707. choice% between 1 and 2 to keep track of which one is selected.
  708.   There isn't much point in doing this as it is much easier for the user to
  709. simply click on the radio icons instead, but it is a good demonstration in
  710. selecting and de-selecting radio icons.
  711.  
  712.   There is a small problem with radio buttons. Try pressing Adjust over a
  713. selected one. You will find that it becomes un-selected. Having none of the
  714. radio buttons selected may be an undesirable situation. It is quite simple
  715. to solve this.
  716.   If you have a look at PROCuser_mouseclick you will see that the third
  717. parameter passed to is is called button%. Basically, if button%=4 then
  718. Select was pressed. If button%=1 then Adjust was pressed. There are also
  719. numbers for combinations of mouse buttons, but we need not concern ourselves
  720. with that at the moment.
  721.   Alter the WHEN 4 and WHEN 5 parts so they look like:
  722.  
  723. WHEN 4 :
  724. IF button%=1 PROCwimp_iconselect(main%,4,1)
  725. choice%=1
  726. WHEN 5 :
  727. IF button%=1 PROCwimp_iconselect(main%,5,1)
  728. choice%=2
  729.  
  730.   Re-load !MyApp and make sure that you always have to have a radio icon
  731. selected.
  732.  
  733.   The last section has an option icon and two buttons. What we want to do
  734. with this section is control the option icon using the buttons, in much the
  735. same way as for the radio icons. There is a difference though, in that at
  736. any one time, one of the buttons will have to be disabled; there is not much
  737. point clicking on 'On' if it is already turned on.
  738.  
  739.   Just before PROCwimp_poll, add the following:
  740.  
  741. option%=0
  742. PROCwimp_icondisable(main%,10)
  743.  
  744.   option% records the state of the option icon, so if the application ever
  745. needed to act upon its state, it could just look at option%. The function
  746. disables (greys out) the 'Off' button (icon number 10). Its duel
  747. PROCwimp_iconenable enables icons and has the same parameters.
  748.  
  749.   In PROCuser_mouseclick, modify it so it is like:
  750.  
  751. WHEN 5 :
  752. IF button%=1 PROCwimp_iconselect(main%,5,1)
  753. choice%=2
  754. WHEN 9 :
  755. PROCwimp_icondisable(main%,9)
  756. PROCwimp_iconenable(main%,10)
  757. PROCwimp_iconselect(main%,8,1)
  758. option%=1
  759. WHEN 10 :
  760. PROCwimp_iconenable(main%,9)
  761. PROCwimp_icondisable(main%,10)
  762. PROCwimp_iconselect(main%,8,0)
  763. option%=0
  764. WHEN 8 :
  765. IF option%=0 THEN
  766. PROCwimp_iconenable(main%,10)
  767. PROCwimp_icondisable(main%,9)
  768. ENDIF
  769. IF option%=1 THEN
  770. PROCwimp_icondisable(main%,10)
  771. PROCwimp_iconenable(main%,9)
  772. ENDIF
  773. option%=ABS(1-option%)
  774.  
  775.   You should be able to see how it works, and know exactly what will happen
  776. when you click on the icons. Run it and check!
  777.  
  778.   Using FNwimp_icondisable and FNwimp_iconenable you can grey out and
  779. un-grey out any icon you wish. If the user clicks on a disabled icon, then
  780. the mouse click is ignored, and PROCuser_mouseclick is not called.
  781.  
  782.   You must have noticed that as soon as you have some un-saved data in a
  783. program, the title of the window has an asterisk added to end. Using DrWimp
  784. this is quite easy to achieve, once you know that you have some unsaved
  785. data...
  786.   For MyApp we will assume that we have some unsaved data when 'OK' or
  787. Return is pressed. FNwimp_getwindowtitle returns a sting containing the
  788. name. PROCwimp_putwindowtitle changes the title to the supplied string. All
  789. we have to do therefore is read the title, add “ *” to the end and put it
  790. back.
  791.  
  792.   Change the WHEN 2 : section in PROCuser_mouseclick to:
  793.  
  794. WHEN 2 :
  795. text$=FNwimp_geticontext(main%,1)
  796. PROCwimp_puticontext(main%,11,text$)
  797. r=1
  798. title$=FNwimp_getwindowtitle(main%)
  799. IF RIGHT$(title$,2)=" *" r=0
  800. IF r=1 PROCwimp_putwindowtitle(main%,title$+" *")
  801.  
  802.   The title is put into title$, then the end is checked to see if “ *” has
  803. already been added (we don't want to add “ *” each time 'OK' is pressed!).
  804. If it hasn't then the asterisk is added. You should now be able to alter a
  805. part of FNuser_keypress so the title changes when Return is pressed as well.
  806.  
  807.   Note: In order to change the window title it must be indirected. This is
  808. set up using a template editor like !TemplEd. The indirected size only needs
  809. to be 1.
  810.  
  811.   Just a quick thing for you to try while I am dealing with windows: Quite a
  812. few programs have a window that appears in the centre of the screen when it
  813. loads. It stays there for a bit before closing again. Using banners is a
  814. good way of announcing your program or reminding people to register it.
  815. DrWimp has a function that handles banners for you. While the banner is on
  816. the screen, you can still use the desktop and your application.
  817.  
  818.   This is how you use it: Just before PROCwimp_poll enter the following
  819. line:
  820.  
  821. PROCwimp_banner(info%,3)
  822.  
  823.   When you load MyApp, the info window will appear for three seconds in the
  824. middle of the screen. The info window isn't really suitable, so I'll leave
  825. it to you to design a window, load it in, and put things like version number
  826. and date, etc in using PROCwimp_puticontext.
  827.  
  828. 5. Advanced menus
  829.  
  830.   So far we have only got a simple two item menu with an info window
  831. (windows off menus are called dialogue boxes). There is a lot more you can
  832. do with menus. This part looks at submenus, ticks, greying out, dotted
  833. lines, changing items' text, and writable menu items.
  834.  
  835.   First of all, lets create a menu for our main window. Below the only
  836. FNwimp_createmenu we have so far, add the following lines:
  837.  
  838. menu$="MyApp/Info>info%/Item 2/Item 3/Item 4/Save"
  839. mainmenu%=FNWimp_createmenu(menu$,0)
  840.  
  841. And attach the menu to the main window by altering FNuser_menu so it looks
  842. like:
  843.  
  844. DEF FNuser_menu(window%,icon%)
  845. CASE window% OF
  846. WHEN ibar% : =barmenu%
  847. WHEN main% : =mainmenu%
  848. ENDCASE
  849. =0
  850.  
  851.   When you press Menu anywhere over the main window, you should get a menu
  852. with 5 items. The first should have a submenu leading to the info window.
  853.  
  854.   Now create another menu by adding the following line ABOVE the menu$=...
  855. you have just entered:
  856.  
  857. i3menu%=FNwimp_createmenu("Item 3/Help/Tick me!",0)
  858.  
  859.   Now you can see from the title of this menu that it is obviously a submenu
  860. for Item 3 on our main menu. Here is how to add it: instead of entering a
  861. window handle, you simply enter a menu handle. For example, change menu$ to:
  862.  
  863. menu$="MyApp/Info>info%/Item 2/Item 3>i3menu%/Item 4/Save"
  864.  
  865. Run MyApp and take a look at the menu. And that is all there is to it! Here
  866. is another example of how easy it is to use:
  867.   Before the i3menu%=... line add the following:
  868.  
  869. tickmenu%=FNwimp_createmenu("Tick me!/Bored/Dull/Waffle",0)
  870.  
  871. And change the i3menu%=... line to read:
  872.  
  873. i3menu%=FNwimp_createmenu("Item3/Help/Tick me!>tickmenu%",0)
  874.  
  875. So you can see that it is quite painless to build up very complex menu
  876. structures.
  877.   As you have seen before, if you choose a menu item then
  878. PROCuser_menuselection is called. If you choose the first item from the menu
  879. tickmenu%, then menu%=tickmenu% and item%=1.
  880.  
  881.   When you create a menu it has no ticks by the side of any items, no dotted
  882. lines separating items, and none of the items greyed out. Any that need to
  883. be done when the application loads, have to be set up after the menu has
  884. been created.
  885.  
  886.   PROCwimp_menutick toggles a tick next to the menu item specified. Add the
  887. following line to the end of PROCuser_menuselection and try it out:
  888.  
  889. IF menu%=tickmenu% AND item%=1 PROCwimp_menutick(menu%,item%)
  890.  
  891.   PROCwimp_menudisable and PROCwimp_menuenable surprisingly enough enable
  892. and disable menu items!
  893.  
  894.   At the end of PROCuser_menuselection, add the following lines and try it
  895. out:
  896.  
  897. IF menu%=mainmenu% AND item%=2 PROCwimp_menudisable(menu%,3)
  898. IF menu%=mainmenu% AND item%=4 PROCwimp_menuenable(menu%,3)
  899.  
  900.   PROCwimp_menudottedline puts a dotted line on the menu below the item
  901. specified. Try it out by adding the following after i3menu% is created:
  902.  
  903. PROCwimp_menudottedline(i3menu%,1)
  904.  
  905.   There are a few more functions related to menus:
  906.  
  907. PROCwimp_menupopup(menu%,bar%,x%,y%)
  908.  
  909.   This brings up the menu menu% at the co-ordinates x%,y% if bar%=0. If
  910. bar%=1 then the menu is positioned for the iconbar icon. This can be useful
  911. for the menu icons (the icons that depict a menu and are usually for to the
  912. right of writable icons, offering the user a choice of strings to enter into
  913. the writable icon). You detect a click with Select or Adjust on the icon,
  914. read the mouse co-ordinates with MOUSE X,Y,B and bring up the menu. You will
  915. need to add some offsets to x% and y% so then menu appears to the side.
  916.  
  917.   The text of a menu item can be read by using FNwimp_getmenutext, passing
  918. the menu handle and the item number. The duel of this is FNwimp_putmenutext.
  919. This allows you to change the text of an item. The text can be up to 78
  920. characters wide, but this would cross the screen, so if you don't know the
  921. length of the string then truncate it.
  922.   Delete the PROCwimp_menudisable lines, and put the following line in the
  923. same place:
  924.  
  925. IF menu%=mainmenu% AND item%=2 THEN
  926. PROCwimp_putmenutext(mainmenu%,3,"ABCDEFGHIJKLMNOPQRS")
  927. ENDIF
  928.  
  929.   Try choosing the second menu item with Adjust. The menu will automatically
  930. adjust its width to accommodate the longest line.
  931.  
  932.   The last major menu function turns an item into a writable one. A block of
  933. memory is reserved to put the text into automatically. After the main menu
  934. has been defined, add the following line:
  935.  
  936. PROCwimp_menuwrite(mainmenu%,4,20)
  937.  
  938.   The first parameter is the menu handle, the second is the item number. It
  939. doesn't matter if some text is already there. The third parameter is the
  940. maximum length allowed to be entered.
  941.  
  942.   The final handful of menu functions don't really need much description.
  943. For more details see !Fnc'n'Prc or section 3 in this manual.
  944.  
  945. FNwimp_menusize(menu%)              - Returns the number of items in a menu.
  946. PROCwimp_menuclose                  - Closes any open menu.
  947. FNwimp_getmenutitle(menu%)          - Returns the title of the menu.
  948. PROCwimp_putmenutitle(menu%,title$) - Changes the menu title to title$.
  949.  
  950. 6. Panes
  951.  
  952.   Using DrWimp, it is very easy to attach a pane to a window. From the
  953. tutorials folder, copy “Template3” into the MyApp directory and rename as
  954. “Templates”.
  955.  
  956.   Where the other windows are loaded in, load in the window “pane”:
  957.  
  958. pane%=FNwimp_loadwindow("<MyApp$Dir>.Templates","pane",1)
  959.  
  960.   The pane wants to be attached to the main window. When the main window is
  961. dragged about, it is actually being continually re-opened all the time. This
  962. means that PROCuser_openwindow is also being called continually. All we have
  963. to do is open the pane next to the main window. In PROCuser_openwindow, add
  964. the following lines:
  965.  
  966. IF window%=main% THEN
  967. xoff%=x%-FNwimp_getwindowsize(pane%,0)
  968. PROCwimp_openwindowat(pane%,xoff%,y%,stack%)
  969. ENDIF
  970.  
  971.   The pane also needs to be closed when the main window is, so in
  972. PROCuser_closewindow add the following line:
  973.  
  974. IF window%=main% PROCwimp_closewindow(pane%)
  975.  
  976.   There is one last thing to do; add the following line to PROCuser_pane:
  977.  
  978. IF window%=main% =pane%
  979.  
  980.   Re-load MyApp and check that it is working. And that is all there is to
  981. it! Just a quick explanation of a few things:
  982.  
  983.   PROCwimp_openwindowat opens the specified window so the top left corner is
  984. at the co-ordinates x%,y%. If you want the window to open at the top, then
  985. stack%=-1, or at the bottom, then stack%=-2. If you want the window to open
  986. behind a certain one, then stack%=the handle of the window to open behind.
  987.  
  988.   If you want a window to open with another one but not follow it around,
  989. then in PROCuser_openwindow, use PROCwimp_openwindow. If you set the second
  990. parameter to 1 then it will continually re-centre, so it is best to set it
  991. to 0. Also, just pass stack% straight through.
  992.  
  993. 7. Save windows
  994.  
  995.   Adding and controlling save windows is very easy. Copy the file
  996. “Template3” from the tutorial folder into the MyApp directory and rename to
  997. “Templates”. Now load in the save window, and modify the main menu to gain
  998. access to it:
  999.  
  1000. save%=FNwimp_loadwindow("<MyApp$Dir>.Templates","save",1)
  1001.  
  1002. menu$="MyApp/Info>info%/Item 2/Item 3>i3menu%/Item 4/Save>save%"
  1003.  
  1004.   If you run MyApp now, the save window will behave like any other window
  1005. that hasn't got any code to tell it what to do. Everything starts to work
  1006. when you add the following line to PROCuser_savefiletype:
  1007.  
  1008. IF window%=save% ="FFF"
  1009.  
  1010.   DrWimp now knows that save% is a save window and that it saves text files.
  1011. Don't try to save just yet as you will crash the machine (there is no data
  1012. to save).
  1013.   When the icon is dragged to a destination, PROCuser_savedata is called.
  1014. This is where you do the actual saving. path$ is the full pathname of the
  1015. file that you are saving to and window% is the handle of the window that the
  1016. icon was dragged from.
  1017.   Don't always assume that the pathname in path$ will be something like
  1018. “IDEFS::Andy.$.TextFile”, It could be a system variable that the wimp
  1019. expands to a full pathname later on.
  1020.  
  1021. So, enter the following into PROCuser_savedata:
  1022.  
  1023. IF window%=save% THEN
  1024. file%=OPENOUT(path$)
  1025. BPUT#file%,"This is a text file,"
  1026. BPUT#file%,"from MyApp you know!"
  1027. CLOSE#file%
  1028. ENDIF
  1029.  
  1030. Note: the filetyping is taken care of by DrWimp.
  1031.  
  1032.   You can now drag the icon to the filer or other applications. The error
  1033. messages “You must drag the icon to a filer window to save...” are taken
  1034. care of by DrWimp.
  1035.  
  1036.   It is very easy to add lots more save windows. Simply load them in, add
  1037. them to a menu (or provide some way the user can get to them), return their
  1038. filetype from PROCuser_savefiletype, and do the saving in PROCuser_savedata!
  1039.  
  1040. 8. Errors
  1041.  
  1042.   If you get an error or you are trying to debug a program, error windows
  1043. can be very useful. They can tell you information while the program is
  1044. running.
  1045.   Error windows can be altered quite a bit, so there are several parameters
  1046. needed to bring one up. There are two wimp functions for error windows:
  1047.  
  1048. PROCwimp_error(title$,error$,button%,prefix%)
  1049.  
  1050.   This one is the most common. title$ is the title of the window. This is
  1051. usually the application name. error$ is the error message itself. The text
  1052. is wordwrapped automatically. This type of error window can display either
  1053. an 'OK' button, or a 'CANCEL' button. This is controlled by button%. If it
  1054. is 1 then you get an 'OK' button. If it is a 2 then you get a 'CANCEL'
  1055. button. prefix% allows you to tailor the title to suit the error message. If
  1056. prefix% is 0 then the title is title$. If it is 1 then the title is prefixed
  1057. with “Error from ”. And if it is 2 then the title is prefixed by “Message
  1058. from ”.
  1059.  
  1060. FNwimp_errorchoice(title$,error$,prefix%)
  1061.  
  1062.   This is the other function. The parameters act in exactly the same way as
  1063. for PROCwimp_error. This function displays an error window with an 'OK'
  1064. button and a 'CANCEL' button. If 'OK' is clicked on then the function
  1065. returns a TRUE (-1). If 'CANCEL' is clicked on then it returns a FALSE (0).
  1066.  
  1067. 9. Message files
  1068.  
  1069.   It is getting increasingly common for applications to have Message files.
  1070. These files have most of the text for the application in, so it can be
  1071. easily translated by someone who doesn't need to know anything about
  1072. programming.
  1073.  
  1074.   Copy the “Messages” file from the tutorial folder into the MyApp
  1075. directory. Load it into !Edit and have a look at it.
  1076.   Comments start with a hash “#”. Lines which have text on to be used in the
  1077. application start with what is called a token. This is just a few letters
  1078. that the line can be identified by. The token and the text are separated by
  1079. a colon. For example:
  1080.  
  1081. LIB:Doctor Wimp
  1082.  
  1083.   If we wanted to use the line of text “Doctor Wimp” then we would reference
  1084. it by using the token “LIB”.
  1085.  
  1086.   Lines of text can also have strings inserted into them when they are read
  1087. into the application. For example:
  1088.  
  1089. VER:1.00 (%0-%1-95)
  1090.  
  1091.   When you read in this line, you supply two strings. These could be “29“
  1092. and “Mar” for example. When the line is read in it ends up as “1.00
  1093. (29-Mar-95)”.
  1094.  
  1095.   PROCwimp_initmessages(pathname$) sets up blocks of memory ready to read in
  1096. the lines of text. pathname$ is the full pathname to the Messages file.
  1097.  
  1098.   Somewhere before the PROCwimp_poll, call the function for the Messages
  1099. file inside the MyApp directory.
  1100.  
  1101.   To read a line without substituting any strings you can use
  1102. FNwimp_messlook0(token$). This returns the line of text.
  1103.   To read a line and replace “%0” with a string you can use
  1104. FNwimp_messlook1(token$,a$), where “%0” in the messages file is replaced
  1105. with a$.
  1106.   To read and substitute two strings you can use
  1107. FNwimp_messlook2(token$,a$,b$).
  1108.   Add the following lines after PROCwimp_initmessages:
  1109.  
  1110. lib$=FNwimp_messlook0("LIB")
  1111. PROCwimp_error(appname$,"LIB="+lib$,1,2)
  1112. os$=FNwimp_messlook1("OS","3.11")
  1113. PROCwimp_error(appname$,"OS="+os$,1,2)
  1114. ver$=FNwimp_messlook2("VER","29","Mar")
  1115. PROCwimp_error(appname$,"VER="+ver$,1,2)
  1116.  
  1117. 10. Loading data
  1118.  
  1119.   This is very simple to do. Whenever a file (or directory or application)
  1120. is dropped onto a window belonging to your application, then
  1121. PROCuser_loaddata is called. This is where you actually load it in to a
  1122. block of memory or an array.
  1123.   path$ is the full pathname of the file to load from. Don't always assume
  1124. that it is something like : “IDEFS::Andy.$.TextFile”.
  1125.   window% and icon% are the window handle and the icon number that the file
  1126. was dropped on to. Most of the time you would only need to check if it was a
  1127. window or the iconbar icon, but it can be used for drop-boxes. These are
  1128. boxes with text in saying something like: “Drop file to load here”.
  1129.   ftype$ is the filetype of the file to load. Eg: for text files it is
  1130. “FFF”. Files have a three character hexadecimal filetype, but directories
  1131. are &1000, and applications are &2000.
  1132.   If you decide to load in the file after looking at all the parameters,
  1133. then you must load it in and return a 1. This is so DrWimp can send a
  1134. message to the filer or any other application that the file came from,
  1135. saying that it has been loaded.
  1136.  
  1137.   Here is an example piece of code for loading in a text file in
  1138. PROCuser_loaddata
  1139.  
  1140. DEF PROCuser_loaddata(path$,window%,icon%,ftype$)
  1141. used=0
  1142. IF ftype$="FFF" THEN
  1143. file%=OPENIN(path$)
  1144. L=1
  1145. REPEAT
  1146. A$(L)=GET$#file%
  1147. L+=1
  1148. UNTIL EOF#file%
  1149. CLOSE#file%
  1150. lines%=L-1
  1151. used=1
  1152. ENDIF
  1153. =used
  1154.  
  1155.   What it does is load in a text file into an array called A$ (which you
  1156. will need to create before PROCwimp_poll). At the end, lines%=the number of
  1157. lines read in.
  1158.  
  1159.   Try altering MyApp so it can load in a text file, then using the save box,
  1160. allow the user to save the text file to somewhere else. All you have to do
  1161. is alter the save code so it saves the array.
  1162.  
  1163. 11. Interactive help
  1164.  
  1165.   DrWimp supports interactive help applications like Acorn's !Help. All you
  1166. have to do is return the help string for a given window handle and icon
  1167. number. FNuser_help is where you do this.
  1168.  
  1169.   Enter the following line into FNuser_help, reload MyApp, load !Help, and
  1170. move the pointer over the info window and the iconbar icon:
  1171.  
  1172. DEF FNuser_help(window%,icon%)
  1173. h$=""
  1174. CASE window% OF
  1175. WHEN info% :
  1176. CASE icon% OF
  1177. WHEN 1 : h$="This application is called 'MyApp' "
  1178. WHEN 2 : h$="It tests the DrWimp library"
  1179. WHEN 3 : h$="MyApp was written by Joe Bloggs"
  1180. WHEN 4 : h$="This is the version number and date"
  1181. OTHERWISE : h$="This is the MyApp info window."
  1182. ENDCASE
  1183. WHEN ibar% : h$="This is the MyApp icon."
  1184. ENDCASE
  1185. =h$
  1186.  
  1187. 12. Sprite areas & Mouse pointers
  1188.  
  1189.   Whenever the pointer moves in and out of one of MyApp's windows, the
  1190. functions PROCuser_enteringwindow and PROCuser_leavingwindow are called.
  1191. This makes it very easy to change the mouse pointer when it is over one of
  1192. your windows. There is a function to change the pointer for you, but first I
  1193. will look at sprite areas as it is closely related:
  1194.  
  1195.   All the sprites in the windows so far are from the wimp sprite pool. An
  1196. application can however, create it's own private sprite area that is stored
  1197. in the wimpslot, or memory used by the application. This has the advantage
  1198. that when the application quits, all the memory is regained.
  1199. PROCwimp_loadsprites does all the work for you. Passed to it is a pathname
  1200. to a sprite file, and the area is set up and the file is loaded in. The
  1201. sprites in that area can then be used in windows (see PROCwimp_loadwindow
  1202. for parameters), or for pointers.
  1203.  
  1204.   PROCwimp_pointer controls the mouse pointer. Pointer number two is always
  1205. used for the second one.
  1206.  
  1207.   Copy the file “Sprites” from the tutorials folder into the MyApp
  1208. directory. Enter the following line after FNwimp_initialise:
  1209.  
  1210. PROCwimp_loadsprites("<MyApp$Dir>.Sprites")
  1211.  
  1212.   In PROCuser_enteringwindow, add the following lines:
  1213.  
  1214. IF window%=main% THEN
  1215. PROCwimp_pointer(1,1,"ptr_hand")
  1216. ENDIF
  1217.  
  1218.   And in PROCuser_leavingwindow, add the following:
  1219.  
  1220. IF window%=main% THEN
  1221. PROCwimp_pointer(0,0,"")
  1222. ENDIF
  1223.  
  1224.   Run MyApp and you should find that when you move the pointer over the main
  1225. window, it turns into a hand. The first parameter tells DrWimp whether to
  1226. use the default pointer, or a user defined one. The second parameter should
  1227. be 0 for the wimp sprite pool, and 1 for a user sprite area. The default
  1228. pointer can be found in the RMA, so it should be a 0 to use it. The last
  1229. parameter is the name of the sprite to use for the user defined pointer. If
  1230. you are using the default pointer, then you don't need to put anything into
  1231. the string.
  1232.  
  1233.   It is a good idea to change the pointer into one looking like a caret when
  1234. it is over a writable icon. For this, you need to have the pointer in the
  1235. wimp sprite area (*IconSprites a file with “ptr_write” in), and in the
  1236. validation field of the icon enter:
  1237.  
  1238. R7;Pptr_write
  1239.  
  1240.   You can do similar things with other icons like the menu ones. !Impression
  1241. is a good example.
  1242.  
  1243. 13. Redraws, leafnames & versions
  1244.  
  1245.   If you have some user graphics in a window, that can't be redrawn by the
  1246. wimp, then it will ask you to do the redraw. For example, you could be using
  1247. the CIRCLE command to draw a circle in a window.
  1248.   When a redraw is required, PROCuser_redraw is called. The handle of the
  1249. window is passed, and the position of the rectangle. The rectangle is like a
  1250. graphics window, so you can redraw all the window contents if you like
  1251. (although that is a bit slow). Anything outside is clipped.
  1252.  
  1253.   Sometimes it can be useful to get a leafname from a pathname.
  1254.  
  1255.   pathname = “IDEFS::Andy.$.Progs.Project1.!Wow.Sprites”
  1256.   leafname = “Sprites”
  1257.  
  1258.   DrWimp can do this for you with FNwimp_getleafname(pathname$). It returns
  1259. the leafname.
  1260.  
  1261.   It is very likely that the DrWimp library will have some modifications or
  1262. improvements made to it at some point. I very much hope that they will not
  1263. affect the way any existing wimp or user functions are called, but just in
  1264. case, you can call a function to read the version number of the library. So
  1265. if someone decides to replace the library in your application with a newer
  1266. version, then your program can read the version number and refuse to work
  1267. with it.
  1268.  
  1269.   FNwimp_libversion returns the version number x 100. So if it is version
  1270. 1.43 then it will return 143.
  1271.  
  1272. 14. Changing sprites
  1273.  
  1274.   If you have an icon which is a sprite (like the text file icon in the save
  1275. window) then you can change it to another sprite by using
  1276. PROCwimp_puticontext. This will only work however, if the icon is
  1277. indirected. That is set up using a template editor.
  1278.  
  1279.   For example: insert the following line just before PROCwimp_poll:
  1280.  
  1281. PROCwimp_puticontext(save%,0,"file_ffd")
  1282.  
  1283.   Re-load MyApp and the file icon in the save window will now be a Data one.
  1284.  
  1285. 15. Large menus & rebuilds
  1286.  
  1287.   Yes, this section is again concerned with menus. In particualar: how to
  1288. create very large menus, how to completely change a menu (ie. a re-build),
  1289. and add and remove items.
  1290.  
  1291.   Menus can be created so that they are dynamic. In other words, then can
  1292. grow and shrink in accordance with what your application wants.
  1293.   You should recall from the introduction section that when a menu is
  1294. created a block of memory of a fixed size is reserved to put the data that
  1295. the wimp needs in. So for example:
  1296.  
  1297. menu%=FNwimp_createmenu("MyApp/Info/Quit",0)
  1298.  
  1299. will reserve a block of memory just big enough to hold the menu with only
  1300. the two items specified.
  1301.   But what happens if you want to add another item to the menu. This will
  1302. create three items, so all the data for one item will be pushed into the
  1303. next part of the memory. This could be holding the contents of variables
  1304. that you are using, thus corrupting them, or even more likely you will crash
  1305. the application, because you are trying to write to some memory addresses
  1306. that don't actually exist (address exception errors are the result of this).
  1307.  
  1308.   What is needed is a way of making sure the block of memory is big enough.
  1309. This is where the last parameter to FNwimp_createmenu comes in:
  1310.   If it is less than or equal to the number of items specified in the
  1311. string, then the block of memory will be just big enough to hold the items
  1312. given. If it is bigger, then it is the maximum number of items that can be
  1313. on that menu.
  1314.  
  1315.   So if you used:
  1316.  
  1317. menu%=FNwimp_createmenu("MyApp/Info/Quit",20)
  1318.  
  1319. then you would create a menu the same as before, but you can have up to 20
  1320. items added to it later on.
  1321.  
  1322.   PROCwimp_putmenuitem and PROCwimp_removemenuitem add and remove items from
  1323. menus. Note: no check is made to ensure that the menu is not bigger than the
  1324. block of memory; you will have to make sure that the block is big enough.
  1325.  
  1326. PROCwimp_putmenuitem(menu%,item%,item$)
  1327. PROCwimp_removemenuitem(menu%,item%)
  1328.  
  1329.   The parameters are mainly self explanatory. If item% in
  1330. PROCwimp_putmenuitem is greater that the total number of items+1 then it
  1331. will just be added onto the end.
  1332.   As items are added or removed, items below are shuffled down and up
  1333. respectively.
  1334.  
  1335.   If you wanted to re-build or re-create a menu from scratch again, but
  1336. still have the same handle as the last one, then you could called
  1337. FNwimp_createmenu, which would get another chunk of memory and put the data
  1338. needed into it. This means that the block of memory with the original menu
  1339. in is still occupied and therefore wasted. If you do this repeatedly then
  1340. more and more memory is taken up until your application runs out, crashing
  1341. it.
  1342.   A much better way is to use the wimp function PROCwimp_recreatemenu, which
  1343. updates the data in the block of memory containing the old menu.
  1344.  
  1345. PROCwimp_recreatemenu(menu%,menu$)
  1346.  
  1347.   menu% is the handle of the menu to re-create. menu$ is a string to build
  1348. the menu from, and is in the usual form, eg:
  1349.  
  1350. "MyApp/Info>info%/Quit"
  1351.  
  1352. The number of items in the new menu shouldn't be greater than the specified
  1353. maximum value when FNwimp_createmenu was called. Eg:
  1354.  
  1355. menu%=FNwimp_createmenu("MyApp/Quit",1)
  1356. PROCwimp_recreatemenu(menu%,"MyApp/Info/Quit")
  1357.  
  1358. Would probably cause the application to crash, because not enough memory has
  1359. been allocated for all the items in the larger re-created menu.
  1360.  
  1361.   When a menu is re-created, all the item attributes like dotted lines,
  1362. greying out, and ticks are removed. If you want to change one or two menu
  1363. items to reflect something in your application like: “Save selection” or
  1364. “Save” depending in this case on whether anything was selected or not, then
  1365. use PROCwimp_putmenutext instead as the attributes are retained.
  1366.  
  1367.   Now we come to the last part in this section: FNwimp_createmenu and
  1368. PROCwimp_recreatemenu have a major limitation: very large menus cannot be
  1369. built.
  1370.   If you think about it, the maximum length of a line allowed in BASIC is
  1371. something like 255 characters. Now, when you create a menu some of these are
  1372. used up with the function name and other parameters, leaving maybe 210
  1373. characters left for the string that the menu is created from. So what
  1374. happens if you want to create a font menu where the number of fonts could be
  1375. in the hundreds?
  1376.  
  1377.   DrWimp provides a very easy solution to this which requires modified
  1378. versions of FNwimp_createmenu and PROCwimp_recreatemenu.
  1379.   The solution is to put all the menu items into an array, then build the
  1380. menu from the array. This lends itself very well to reading in items like
  1381. font names, or data from support files for your application.
  1382.  
  1383.   First of all you need to decide the maximum number of items in the menu.
  1384. If you are creating a font menu, then you can use the SWI “Font_ListFonts”
  1385. to find out the number of fonts. Anyway, add one onto the total size, and
  1386. DIM an array.
  1387.  
  1388.   The first element of an array (number 0) is the menu title. The last item
  1389. must be “END”, so DrWimp knows how much of the array to use. Note: “END”
  1390. will not appear as a menu item; the element before it will be the last one.
  1391.   Here is some example code:
  1392.  
  1393. DIM menu$(20)
  1394. menu$(0)="MyApp"
  1395. menu$(1)="Info>info%"
  1396. menu$(2)="Quit"
  1397. menu$(3)="END"
  1398. barmenu%=FNwimp_createmenuarray(menu$(),20)
  1399.  
  1400.   As you can see, elements can contain the submenu pointers in the usual
  1401. way. FNwimp_createmenuarray is passed the name of the array (with empty
  1402. brackets) and the maximum number of items. The last parameter is exactly the
  1403. same as for FNwimp_createmenu, so it could just as easily be “0”, which
  1404. means that more items can't safely be added, but it makes more sense to set
  1405. it as the size of the array.
  1406.  
  1407.   Menus can be re-built using arrays as well. Instead of using
  1408. PROCwimp_recreatemenu, use:
  1409.  
  1410. PROCwimp_recreatemenuarray(menu%,array$())
  1411.  
  1412.   Menus created with a string can be recreated with an array, and
  1413. vice-versa. Note: menus created with arrays can be manipulated using the
  1414. same functions, such as PROCwimp_putmenuitem, PROCwimp_menuwrite, etc. The
  1415. only difference is the way that the data to build the menu initially is
  1416. stored (string or array).
  1417.  
  1418. 16. Multitasking operations
  1419.  
  1420.   This section is about multitasking raytracing, calculating numbers,
  1421. loading data, file finding, etc. No, I am not going to show you how to write
  1422. a raytracer, etc. but show you how to make operations like these multitask
  1423. easily.
  1424.  
  1425.   At the moment, if you wanted to do a multitasking operation, then you
  1426. would have to set NULL to TRUE so PROCuser_null is called continuously, and
  1427. every time it is called, remember where you was up to and do a small bit.
  1428. This can make very tangled code. The difficulty lies in storing where you
  1429. got up to, and this can require a multitude of variables for just one
  1430. operation.
  1431.  
  1432.   A much easier method is to use PROCwimp_singlepoll. When called, it goes
  1433. through the polling loop once. Your operation will already be in some sort
  1434. of loop, so all you have to do is call PROCwimp_singlepoll inside it! This
  1435. very simple technique makes powerful multitasking operations very easy to
  1436. achieve.
  1437.  
  1438.   Change PROCwimp_menuselection so it has lines like:
  1439.  
  1440. CASE menu% OF
  1441. WHEN barmenu% :
  1442. CASE item% OF
  1443. WHEN 1 : PROCchangeauthor
  1444. ENDCASE
  1445. ENDCASE
  1446.  
  1447. And add the following function at the end of !RunImage:
  1448.  
  1449. DEF PROCchangeauthor
  1450. FOR L=1 TO 200
  1451. PROCwimp_singlepoll
  1452. a$=""
  1453. FOR M=1 TO 6
  1454. a$+=CHR$(RND(26)+64)
  1455. NEXT M
  1456. PROCwimp_puticontext(info%,3,a$)
  1457. NEXT L
  1458. ENDPROC
  1459.  
  1460.   Now run !MyApp and choose the first item on the iconbar menu. If you now
  1461. look at the info window, the author field should be constantly changing with
  1462. random letters. You can still use the desktop, although the loop is simple
  1463. so you can't quit !MyApp until it has finished. This can be fixed by using a
  1464. REPEAT UNTIL loop and checking for finished%=TRUE.
  1465.  
  1466.   Note: PROCwimp_singlepoll acts just like PROCwimp_poll, except it doesn't
  1467. quit for you. If one of your icons is clicked on, then PROCwimp_mouseclick
  1468. is still called, and if your application received messages, then they are
  1469. acted on, and so on.
  1470.  
  1471. 17. “Grubby” tasks
  1472.  
  1473.   You will sometimes see tasks that load onto the iconbar, but when the icon
  1474. is clicked on they leave the desktop and monotask. When the user has
  1475. finished, they are returned to the desktop, with the application still
  1476. loaded onto the iconbar. Acorn calls these tasks “Grubby tasks”, and they
  1477. are very simple to implement.
  1478.  
  1479.   Alter PROCwimp_mouseclick so it has a line like:
  1480.  
  1481. CASE window% OF
  1482. WHEN bar% :
  1483. PROCwimp_starttask("BASIC -quit <MyApp$Dir>.Mono")
  1484. ENDCASE
  1485.  
  1486.   Create a BASIC file called “Mono” inside the !MyApp directory containing
  1487. the following:
  1488.  
  1489. MODE12
  1490. PRINT "This is monotasking!"
  1491. A$=GET$
  1492. *DESKTOP
  1493. END
  1494.  
  1495.   Re-load !MyApp and click on the iconbar icon. Press a key to return to the
  1496. desktop. Note: change the mode number to one suitable for your monitor.
  1497.  
  1498.   You will probably want to mangle up the second BASIC file as well as
  1499. !RunImage with DrWimp to give you more security. This is possible if you
  1500. don't use DrWimp in the second BASIC file. Mangle it up with !MakeApp2 and
  1501. !Crunch in the usual way, and then change the PROCwimp_starttask to
  1502. something like:
  1503.  
  1504. PROCwimp_starttask("Run <MyApp$Dir>.Mono")
  1505.  
  1506. 18. Bars
  1507.  
  1508.   When you format a disc a bar increases in size to show the amount of the
  1509. disc that has been formatted so far. When you look at the free space on a
  1510. floppy or hard drive you have several bars to show you how much space has
  1511. been used up, is free, and there is in total. When you open the task display
  1512. you are shown lots of bars that depict the amount of memory something is
  1513. using up.
  1514.  
  1515.   Using DrWimp it is simple to control bars like those yourself. They can
  1516. make information look much more attractive than numbers.
  1517.   DrWimp allows the length of the bars to be changed. This means that they
  1518. can be changed all the time, or only just before a window containing them is
  1519. opened. What you can't do at the moment unfortunately is drag them to
  1520. different sizes.
  1521.  
  1522.   Make a fresh copy of !MyApp. From the Tutorial folder, drag the
  1523. “Template5” file into the !MyApp directory, and rename it as “Templates”.
  1524. Add the following lines at the start of !RunImage, just above PROCwimp_poll:
  1525.  
  1526. main%=FNwimp_loadwindow("<MyApp$Dir>.Templates","main",1)
  1527. bar%=FNwimp_iconbar("!MyApp","",1)
  1528. barmenu%=FNwimp_createmenu("MyApp/Quit",0)
  1529.  
  1530. and in PROCuser_mouseclick:
  1531.  
  1532. IF window%=bar% PROCwimp_openwindow(main%,1,-1)
  1533.  
  1534. and in FNuser_menu:
  1535.  
  1536. IF window%=bar% =barmenu%
  1537.  
  1538. and in PROCuser_menuselection:
  1539.  
  1540. IF menu%=barmenu% AND item%=1 finished%=TRUE
  1541.  
  1542. If you now double-click on !MyApp you should get an icon on the iconbar with
  1543. a menu with a 'Quit' item. Clicking on the icon should produce a small
  1544. window with a red bar in it. What we are going to do is set the bar to a
  1545. random length when it is clicked on.
  1546.  
  1547.   First we need to know what the maximum length is, so load the templates
  1548. into !TemplEd by dropping the file onto !TemplEd's iconbar icon.
  1549.   Open the main window by double-clicking on it in the window at the top
  1550. left. Expand the icon info window at the top right to full size and move the
  1551. pointer over the bar.
  1552.   The icon info window gives the dimensions of 340x36, so the max length is
  1553. 340. Of course we could extend the icon to whatever size we want using
  1554. !TemplEd, and then using that length.
  1555.   Take a look at all the details of the bar icon by double-clicking on it.
  1556. This is how you should set up any icons you want to use as bars. Obviously
  1557. you can change the colour and turn the border on, etc.
  1558.  
  1559.   Returning to !RunImage, add the following line to PROCuser_mouseclick:
  1560.  
  1561. IF window%=main% PROCchangelength
  1562.  
  1563. Now add the following function to the end of !RunImage:
  1564.  
  1565. DEF PROCchangelength
  1566. len=RND(340)
  1567. PROCwimp_bar(main%,1,len)
  1568. ENDPROC
  1569.  
  1570. Re-load !MyApp, and click on the bar or frame icon behind it.
  1571.  
  1572.   It is quite easy to specify the length as a percentage. Alter
  1573. PROCchangelength to:
  1574.  
  1575. DEF PROCchangelength
  1576. len=RND(100)
  1577. len=(340/100)*len
  1578. PROCwimp_bar(main%,1,len)
  1579. ENDPROC
  1580.  
  1581. As you can see, len is a percentage chosen at random.
  1582.  
  1583.   And just to finish off, alter PROCchangelength to:
  1584.  
  1585. DEF PROCchangelength
  1586. pcent=0
  1587. REPEAT
  1588. nlen=(340/100)*pcent
  1589. PROCwimp_bar(main%,1,nlen)
  1590. PROCwimp_singlepoll
  1591. pcent+=2
  1592. UNTIL pcent>100
  1593. ENDPROC
  1594.  
  1595. You should be able to see that it is now the basis for a multi-tasking
  1596. operation with the percentage done depicted by the bar. Put the operation
  1597. inside the loop, and each time round the loop calculate the percentage done
  1598. instead of incrementing it as I have done.
  1599.  
  1600.   You can change the bar to look like however you want it, but I would
  1601. advise against adding any text, sprites, or indirected text.
  1602.   One thing you might like to do is add a border around the bar by clicking
  1603. on the “Border” icon in the relevent !TemplEd window. However, if the bar is
  1604. going to be changing in size rapidly then the part of the border at the
  1605. right edge will flicker a lot as that part of the screen is constantly
  1606. redrawn.
  1607.  
  1608.   Finally, take a look at !Bar in the Examples folder.
  1609.  
  1610.  
  1611. *****************************************************************************
  1612. Section 3 - Functions
  1613. *****************************************************************************
  1614.  
  1615. 1. Windows
  1616.  
  1617. PROCwimp_openwindow(window%,centre%,stack%)
  1618.  
  1619. Opens a window on the screen.
  1620. window% = handle of window to open.
  1621. If centre% = 0 opens window where it was last left on the screen, or if it
  1622. hasn’t been opened before, then where it is positioned in the template file.
  1623. If centre% = 1 opens the window centred on the screen (mode independent).
  1624. stack% = window handle to open behind, or -1 for top of window stack, or -2
  1625. for bottom.
  1626.  
  1627.  
  1628. PROCwimp_openwindowat(window%,x%,y%,stack%)
  1629.  
  1630. Opens a window on the screen so the top left of the window is at
  1631. co-ordinates x%,y%. window% = handle of window to open. stack% = window
  1632. handle to open behind, or -1 for top of window stack, or -2 for bottom.
  1633. Useful for opening panes exactly where you want them.
  1634.  
  1635.  
  1636. PROCwimp_closewindow(window%)
  1637.  
  1638. Closes a window (removes it from the screen). window% = handle of window to
  1639. close.
  1640.  
  1641.  
  1642. FNwimp_loadwindow(pathname$,window$,sprite%)
  1643.  
  1644. Loads in a window from a templates file and returns a handle for the window.
  1645. pathname$ = full pathname to templates file. window$ = name of window in
  1646. templates file. sprite% = sprite flag. If = 0 then use sprites from user
  1647. sprite area for window. If = 1 then use sprites from the wimp sprite pool
  1648. (RMA).
  1649.  
  1650.  
  1651. PROCwimp_putwindowtitle(window%,title$)
  1652.  
  1653. Changes the window title to title$ window% = handle of window.
  1654.  
  1655.  
  1656. FNwimp_getwindowtitle(window%)
  1657.  
  1658. Returns a string containing the window title. window% = handle of window.
  1659.  
  1660.  
  1661. PROCwimp_banner(window%,delay%)
  1662.  
  1663. Opens window in the centre of the screen for specified delay before closing
  1664. it. window% = handle of window to open. delay% = number of seconds to keep
  1665. window on screen.
  1666.  
  1667.  
  1668. FNwimp_getwindowsize(window%,side%)
  1669.  
  1670. Returns the dimension required. If side% = 0 returns width. If side% = 1
  1671. returns height. Useful for positioning panes along side “parent” windows.
  1672.  
  1673.  
  1674. 2. Menus
  1675.  
  1676. PROCwimp_menupopup(menu%,bar%,x%,y%)
  1677.  
  1678. Brings up the menu whose handle is menu% at the co-ordinates x%,y%. If
  1679. bar%=1 then the menu will be positioned as for an iconbar menu, otherwise
  1680. use 0. Useful for go-right or menu icons. Read the mouse co-ordinates, and
  1681. apply offsets to get x% and y%.
  1682.  
  1683.  
  1684. FNwimp_createmenu(menu$,size%)
  1685.  
  1686. Creates a menu structure from the string menu$. The menu handle is returned.
  1687. For more information on menu$ see the tutorial on menus. size% = maximum
  1688. number of items allowed. If size% is less than the number of items in menu$,
  1689. then it is increased to the number of items.
  1690.  
  1691.  
  1692. FNwimp_menusize(menu%)
  1693.  
  1694. Returns the number of entries in the menu. menu% = handle of menu.
  1695.  
  1696.  
  1697. PROCwimp_menutick(menu%,item%)
  1698.  
  1699. If the item doesn’t have a tick next to it then this function places one. If
  1700. the item does have a tick then it is removed. menu% = handle of menu. item%
  1701. = item number (top item is 1).
  1702.  
  1703.  
  1704. PROCwimp_menudisable(menu%,item%)
  1705.  
  1706. Greys out the menu item so it is un-selectable. menu% = handle of menu.
  1707. item% = item number (top item is 1).
  1708.  
  1709.  
  1710. PROCwimp_menuenable(menu%,item%)
  1711.  
  1712. Un-greys out the menu item so it is selectable. menu% = handle of menu.
  1713. item% = item number (top item is 1).
  1714.  
  1715.  
  1716. PROCwimp_menudottedline(menu%,item%)
  1717.  
  1718. Adds a dotted line to the menu below the item. menu% = handle of menu. item%
  1719. = number of item (top item is 1).
  1720.  
  1721.  
  1722. PROCwimp_menuclose
  1723.  
  1724. Closes the currently active menu.
  1725.  
  1726.  
  1727. FNwimp_getmenutitle(menu%)
  1728.  
  1729. Returns a string containing the title of the menu. menu% = handle of menu.
  1730.  
  1731.  
  1732. PROCwimp_putmenutitle(menu%,title$)
  1733.  
  1734. Changes the title of the menu. If the title>11 characters then it is
  1735. truncated. menu% = handle of menu. title$ = new title.
  1736.  
  1737.  
  1738. PROCwimp_putmenutext(menu%,item%,text$)
  1739.  
  1740. Replaces menu items text with text$. menu% = handle of menu. item% = number
  1741. of item (Top item is 1). Can be up to 78 characters long. Automatically
  1742. calculates the new width of the menu.
  1743.  
  1744.  
  1745. PROCwimp_menuwrite(menu%,item%,length%)
  1746.  
  1747. Makes the menu item writable. menu% = handle of menu. item% = number of item
  1748. (top item is 1). length% = maximum length of text allowed to be entered.
  1749.  
  1750.  
  1751. FNwimp_getmenutext(menu%,item%)
  1752.  
  1753. Returns a string containing the text of the menu item. menu% = handle of
  1754. menu. item% = number of item (top item is 1).
  1755.  
  1756.  
  1757. PROCwimp_putmenuitem(menu%,item%,item$)
  1758.  
  1759. If the menu is dynamic then item$ will be put into menu item item%. Any
  1760. items below will be shuffled down. If item% is bigger than the current
  1761. number of items+1, then it will be added to the bottom. menu% = handle of
  1762. menu.
  1763.  
  1764.  
  1765. PROCwimp_removemenuitem(menu%,item%)
  1766.  
  1767. Removes the item from the menu. Any items below are shuffled up. If there is
  1768. only one item on the menu, then it cannot be removed. menu% = handle of
  1769. menu. item% = number of item to remove.
  1770.  
  1771.  
  1772. PROCwimp_recreatemenu(menu%,menu$)
  1773.  
  1774. Rebuilds the menu using the string menu$. More items can be included than
  1775. the first time as long as you don’t go over the pre-defined limit. menu% =
  1776. handle of menu to rebuild.
  1777.  
  1778.  
  1779. FNwimp_createmenuarray(array$(),size%)
  1780.  
  1781. Creates a menu from the array supplied. Each item of the menu is in a
  1782. seperate element of the array. eg: array$(3)=‘Info>info%’. Note submenus are
  1783. included in the usual way. the first element is the menu title, and the last
  1784. must be ‘END’. array$() = array to get items from. size% = maximum number of
  1785. elements to allocate room for (doesn’t have to be the current number).
  1786. Returns a handle to the menu.
  1787.  
  1788.  
  1789. PROCwimp_recreatemenuarray(menu%,array$())
  1790.  
  1791. Rebuilds the menu using the items in the array. The first array item
  1792. (array$(0)) is the menu title, and the last has to be ‘END’. Things like
  1793. ticks and dotted lines are reset. Submenus are included with each item in
  1794. the usual way, ie. array$(4)=‘Info>info%’. menu% = handle of menu to rebuild
  1795. array$() = array to get items from.
  1796.  
  1797.  
  1798. 3. Icons
  1799.  
  1800. FNwimp_iconbar(sprite$,text$,pos%)
  1801.  
  1802. Places an icon on the iconbar. Returns a handle to the window containing the
  1803. iconbar icon. sprite$ = name of sprite to put on iconbar. text$ = text to
  1804. put underneath the icon eg. like the floppy drive icon. If text$ = “” then
  1805. no text will be used, and the icon will be positioned correctly. pos% =
  1806. controls the position of the icon. If pos% = 1 then the icon will appear on
  1807. the right. If pos% = 0 then it will appear on the left.
  1808.  
  1809.  
  1810. FNwimp_geticontext(window%,icon%)
  1811.  
  1812. Returns a string containing the text from the icon. window% = handle of
  1813. window containing icon. icon% = icon number.
  1814.  
  1815.  
  1816. PROCwimp_puticontext(window%,icon%,text$)
  1817.  
  1818. If the icon is indirected then the text in the icon is replaced with text$.
  1819. If the icon is not indirected then an error is caused. Can also be used to
  1820. change the sprite in the icon. window% = handle of window containing icon.
  1821. icon% = number of icon.
  1822.  
  1823.  
  1824. PROCwimp_puticonbartext(text$)
  1825.  
  1826. If the iconbar icon has text underneath it then it is replaced by text$.
  1827.  
  1828.  
  1829. PROCwimp_iconbarsprite(sprite$)
  1830.  
  1831. Changes the sprite used for the iconbar icon to sprite$.
  1832.  
  1833.  
  1834. PROCwimp_putcaret(window%,icon%)
  1835.  
  1836. Puts the caret in the icon. window% = handle of window containing icon.
  1837. icon% = number of icon.
  1838.  
  1839.  
  1840. PROCwimp_losecaret
  1841.  
  1842. Removes the caret from the icon it is in.
  1843.  
  1844.  
  1845. PROCwimp_iconenable(window%,icon%)
  1846.  
  1847. Un-greys out icon so it can be selected. window% = handle of window
  1848. containing icon. icon% = number of icon.
  1849.  
  1850.  
  1851. PROCwimp_icondisable(window%,icon%)
  1852.  
  1853. Greys out icon so it cannot be selected. window% = handle of window
  1854. containing icon. icon% = number of icon.
  1855.  
  1856.  
  1857. PROCwimp_iconselect(window%,icon%,state%)
  1858.  
  1859. Selects (inverts) and un-selects icon. window% = handle of window containing
  1860. icon. icon% = number of icon. If state% = 0 icon is un-selected. If state% =
  1861. 1 icon is selected. Useful for making an icon appear to be clicked on when
  1862. Return is pressed in a writable icon.
  1863.  
  1864.  
  1865. 4. Messages
  1866.  
  1867. PROCwimp_initmessages(pathname$)
  1868.  
  1869. Reserves blocks of memory and sets up Messages file for use. pathname$ =
  1870. full pathname of messages file to use.
  1871.  
  1872.  
  1873. FNwimp_messlook0(token$)
  1874.  
  1875. Returns the string in the messages file for the token token$.
  1876.  
  1877.  
  1878. FNwimp_messlook1(token$,a$)
  1879.  
  1880. Returns the string in the messages file for the token token$. Any ‘%0’s in
  1881. the string are replaced with a$ before returning.
  1882.  
  1883.  
  1884. FNwimp_messlook2(token$,a$,b$)
  1885.  
  1886. Returns the string in the messages file for the token token$. Any ‘%0’s and
  1887. ‘%1’s are replaced with a$ and b$ respectively before returning.
  1888.  
  1889.  
  1890. 5. Misc
  1891.  
  1892. FNwimp_initialise(name$,wimpmem%,iconmem%)
  1893.  
  1894. This function registers your application with the Task Manager and reserves
  1895. some memory. name$ = the name of your application eg. ‘Draw’. wimpmem% =
  1896. number of bytes to reserve for icon data or menu entries. iconmem% = number
  1897. of bytes to reserve for indirected text. eg. window titles or long menu
  1898. entries.
  1899.  
  1900.  
  1901. PROCwimp_poll
  1902.  
  1903. This function is the main loop of your application When it has finished,
  1904. your application has quitted. If something happens to your application eg.
  1905. an icon has been clicked on, then the relevant function will be called from
  1906. the loop. Set finished% to TRUE to quit.
  1907.  
  1908.  
  1909. PROCwimp_error(title$,error$,button%,prefix%)
  1910.  
  1911. Reports an error using a standard error box. title$ = title of error window.
  1912. error$ = error message. IF button%=1 then will have an ‘OK’ button. IF
  1913. button%=2 then will have a ‘CANCEL’ button. prefix% = prefix flag. If = 0
  1914. then the title is title$. If = 1 then the title is prefixed by ‘Error from
  1915. ’. If = 2 then the title is prefixed by ‘Message from ’.
  1916.  
  1917.  
  1918. FNwimp_errorchoice(title$,error$,prefix%)
  1919.  
  1920. Reports an error using a standard error box. It has both ‘OK’ and ‘CANCEL’
  1921. buttons. title$ = title of error window. error$ = error message. IF prefix%
  1922. = 0 then the title is title$. If prefix% = 1 then the title is prefixed by
  1923. ‘Error from ’. If prefix% = 2 then the title is prefixed by ‘Message from ’.
  1924. Returns TRUE if ‘OK’ pressed. FALSE if ‘CANCEL’ pressed.
  1925.  
  1926.  
  1927. PROCwimp_loadsprites(pathname$)
  1928.  
  1929. Creates a user sprite area and loads the sprites into it so they can be used
  1930. in windows, etc. pathname$ = full pathname to sprite file.
  1931.  
  1932.  
  1933. FNwimp_getleafname(pathname$)
  1934.  
  1935. Returns a string containing the leafname from the pathname. pathname$ =
  1936. pathname.
  1937.  
  1938.  
  1939. PROCwimp_pointer(pointer%,area%,pointer$)
  1940.  
  1941. Changes mouse pointer between the default (number 1) and the user defined
  1942. pointer (number 2). If pointer% = 0 default pointer is used. If pointer% = 1
  1943. user defined pointer is used. If area% = 0 wimp sprite pool is used. If
  1944. area% = 1 user sprite area is used. pointer$ = sprite name of pointer.
  1945.  
  1946.  
  1947. PROCwimp_starttask(command$)
  1948.  
  1949. Sends command$ to the CLI. Omit ‘*’.
  1950.  
  1951.  
  1952. FNwimp_libversion
  1953.  
  1954. Returns the version number of the library x 100. Eg. if the version of the
  1955. library is 1.03 then 103 will be returned.
  1956.  
  1957.  
  1958. FNwimp_sysvariable(sysvar$)
  1959.  
  1960. Returns a string for the system variable sysvar$. Note ‘<’ and ‘>’ are not
  1961. required in sysvar$.
  1962.  
  1963.  
  1964. PROCwimp_bar(window%,icon%,length%)
  1965.  
  1966. Changes the length of the bar to length%. window% = handle of window
  1967. containing bar. icon% = icon number of bar.
  1968.  
  1969.  
  1970. 6. User
  1971.  
  1972. PROCuser_redraw(window%,minx%,miny%,maxx%,maxy%)
  1973.  
  1974. When this function is called, the Wimp wants you to update the specified box
  1975. on the screen. The box is in the work area of the window whose handle is
  1976. window%. minx%,miny% = bottom left co-ordinates of box. maxx%,maxy% = top
  1977. right co-ordinates of box.
  1978.  
  1979.  
  1980. PROCuser_mouseclick(window%,icon%,button%)
  1981.  
  1982. IF an icon has been clicked on in one of your windows then this function is
  1983. called. window% = handle of window containing icon. icon% = number of the
  1984. icon clicked on. button% = which mouse button was pressed. Eg. 4 for Select,
  1985. 1 for Adjust.
  1986.  
  1987.  
  1988. FNuser_menu(window%,icon%)
  1989.  
  1990. IF the specified window (and icon) has a menu which you want to appear when
  1991. Menu is pressed over it, then this function should return the handle of the
  1992. menu. window% = handle of window. icon% = number of icon.
  1993.  
  1994.  
  1995. PROCuser_openwindow(window%,x%,y%,stack%)
  1996.  
  1997. IF this function is called, then the window whose handle is window% has been
  1998. opened with the top left of the window at x%,y% on the screen. stack% =
  1999. window handle to open behind, or -1 for top of window stack, or -2 for
  2000. bottom.
  2001.  
  2002.  
  2003. PROCuser_closewindow(window%)
  2004.  
  2005. IF this function is called, then the window whose handle is window% has just
  2006. been closed.
  2007.  
  2008.  
  2009. FNuser_keypress(window%,icon%,code%)
  2010.  
  2011. IF a key is pressed while one of your windows has the input focus, or a
  2012. hotkey is pressed, then this function is called. If you don’t use the key
  2013. then return a 0. If you do then return a 1. window% = handle of window with
  2014. input focus. icon% = number of icon with caret. code% = key code. For most
  2015. keys it is an ASCII number.
  2016.  
  2017.  
  2018. Key         Alone     +Shift    +Ctrl      +Ctrl Shift
  2019. Escape      &1B       &1B       &1B        &1B
  2020. Print (F0)  &180      &190      &1A0       &1B0
  2021. F1-F9       &181-189  &191-199  &1A1-1A9   &1B1-1B9
  2022. Tab         &18A      &19A      &1AA       &1BA
  2023. Copy        &18B      &19B      &1AB       &1BB
  2024. left arrow  &18C      &19C      &1AC       &1BC
  2025. right arrow &18D      &19D      &1AD       &1BD
  2026. down arrow  &18E      &19E      &1AE       &1BE
  2027. up arrow    &18F      &19F      &1AF       &1BF
  2028. Page down   &19E      &18E      &1BE       &1AE
  2029. Page up     &19F      &18F      &1BF       &1AF
  2030. F10-F12     &1CA-1CC  &1DA-1DC  &1EA-1EC   &1FA-1FC
  2031. Insert      &1CD      &1DD      &1ED       &1FD
  2032.  
  2033.  
  2034. PROCuser_menuselection(menu%,item%)
  2035.  
  2036. This function is called when the user has chosen a menu item from one of
  2037. your menus. menu% = handle of menu. item% = item number (top item is 1).
  2038.  
  2039.  
  2040. PROCuser_savedata(pathname$,window%)
  2041.  
  2042. When the user is required to save data, this function is called. pathname$ =
  2043. full pathname of file to save data to. window% = handle of save window icon
  2044. was dragged from.
  2045.  
  2046.  
  2047. FNuser_loaddata(pathname$,window%,icon%,filetype$)
  2048.  
  2049. You load data here. pathname$ = full pathname of source file. window% =
  2050. handle of window file was dragged on to. icon% = number of icon file was
  2051. dragged on to. filetype$ = filetype of file to be loaded. Eg. “FFF”.
  2052.  
  2053.  
  2054. FNuser_savefiletype(window%)
  2055.  
  2056. You return the filetype for the save windows. eg. =‘FFF’. For windows that
  2057. aren’t save windows, return an empty string eg. =‘’. window% = handle of
  2058. window%
  2059.  
  2060.  
  2061. FNuser_help(window%,icon%)
  2062.  
  2063. Return a string to be used for interactive help for the window (and icon).
  2064. window% = handle of window (containing icon). icon% = number of icon.                     
  2065.  
  2066.  
  2067. PROCuser_enteringwindow(window%)
  2068.  
  2069. This function is called when the pointer enters a window. window% = handle
  2070. of window.
  2071.  
  2072.  
  2073. PROCuser_leavingwindow(window%)
  2074.  
  2075. This function is called when the pointer leaves a window. window% = handle
  2076. of window.
  2077.  
  2078.  
  2079. FNuser_pane(window%)
  2080.  
  2081. IF the window has a pane attached to it, then this function should return
  2082. the window handle of the pane. If the window doesn’t have a pane attached,
  2083. then it should return a -1. window% = handle of window.
  2084.  
  2085.  
  2086. PROCuser_null
  2087.  
  2088. This is called continuously. So if you are writing something like a clock,
  2089. you would monitor the time here and change any windows as required. IF you
  2090. want to use this function then set NULL=TRUE.
  2091.  
  2092.