Steve Mumford tackles window creation in this month's tutorial.
At the end of last month's endeavours, we'd written a program that sat on the icon bar and produced error boxes whenever the user had the temerity to click on it. This time around, I've included functions that load a template file from the application directory and create a window, complete with icons. I've added handlers for some more events and messages which allow the window to be moved about, sized, closed and opened - as well as change the text in one of the icons.
The first step in adding windows to your application is the design of the windows themselves. They're described by complicated blocks of data which cover everything from their appearance to their contents. It's possible to do this in a rather abstract manner from within the code by filling in the data block by hand, but most people just find it easier to use Acorn's FormEd application or something similar to build a window description in a more intuitive WYSIWYG environment. It's also a lot easier to alter the layout of your windows once you've finished; because they're saved as a separate file, you don't need to recompile the main program.
Once you have a template file that meets your requirements, the next stage is to import the information from it at an appropriate point during the initialisation of the program. This is achieved using three SWI commands, namely Wimp_OpenTemplate, Wimp_LoadTemplate and Wimp_CloseTemplate. The first and the last of these prepare the computer for reading a file and tidy up afterwards respectively - Wimp_OpenTemplate takes a pointer to the filename in R1, and Wimp_CloseTemplate takes no parameters.
In order to load a template, the user must provide two buffers, large enough to hold all the window and icon data. It's possible to determine th exact size required with a preliminary call, but in this simple example I've taken the easy way out and assigned an ample amount of memory. Wimp_LoadTemplate takes values in registers 1 to 6 - the first three give the addresses of the template buffer, the workspace area and a pointer to the end of the workspace. The fifth register holds a pointer to a 12-byte name of one of the templates in the file; this name must start at a word-aligned address in memory.
In the example on the cover disc, only one window definition is loaded - if you're loading more than one, you'll either have to create multiple buffers or keep track of the individual windows in one large buffer. Finally, Wimp_CloseTemplate is used to let the program know that the template file is no longer required.
To create the window, the address of the template buffer is copied into R1, and Wimp_CreateWindow returns with the window's handle in R0. This is used to refer to the window throughout the rest of the program, so I've stored it in a global variable. So far, the window hasn't been displayed and it will only appear on the screen when the WIMP is instructed to do so. Its size and position are copied from its data block and passed to Wimp_OpenWindow, and the window is finally pasted on the desktop in all its glory.
The story isn't over yet - we have to add the appropriate event handlers to allow us to resize, move and close the window. The WIMP lets us know when one of these occurs by passing our application an event code of 2 or 3, Open_Window_Request or Close_Window_Request respectively. Luckily, these are simple to deal with as most of the updated information is given to us in a ready-to-use format, so we can just call appropriate SWI immediately.
Finally, the application listens out for the TaskInitialise message, broadcast when a new task is installing itself on the desktop. When one occurs, the task's name is copied into a display icon in the window before it is redran. The upshot of this is that our program is now a limited WIMP watchdog; try leaving it running in the background whilst you work in the desktop - you might be surprised at some of the programs that execute without your knowledge. Next month I'll investigate the methods of creating and maintaining menus, and I'll begin looking at better ways of organising the data we have to handle.
|Source:||Acorn User - 167 - April 1996|