![]() |
|
Published 1998-12-01 Printer-friendly version
Often, as one moves from project to project, a client will request a new feature or capability that you haven't had to implement before. Or, perhaps, you have simply decided to add a new capability to your own products. In this case, it was decided a that new Clarion application would work best as a 'tray' program, by which I mean that it would reside in the 'system tray' at the bottom right of the Windows 95/98/NT taskbar (along with the clock, volume control, etc.).
Being a firm advocate of never re-inventing the wheel, it was time to search and see if a third party product existed that would provide the functionality that we wanted without our having to dig into the ever wonderful world of the Windows API.
Enter WinEvent, an inexpensive ($30 US) collection of tools designed to handle a variety of low-level API functions via a simple to use library and template set. Among its feature set is the ability to 'tray-ize' a program (I think I just invented a new word) just what the doctor ordered.
But wait, as they say, there's more!
CapeSoft, a well-known and long-time CW third-party vendor, originally designed WinEvent to ease the task of sub-classing a window within Clarion. What is sub-classing and why would you want to do it? Well, the simple explanation is that every time anything happens in relation to your program (while it is running, of course), Windows sends it a message. Is the mouse over your window? You get hordes of mouse related messages. Was the window moved? You get messages telling your program to repaint the window at the new location. Was the window covered up by another program? You get messages invalidating portions of your window and telling you to redraw it when it is exposed again. In fact, I'm sure you get the message by now messages are flying around thicker than mosquitoes at a nudist colony.
But, you say, why don't I see these messages? Because the Clarion run-time library intercepts them, processes them, and then passes on a small subset of them to you as Events. For example, you never see all those messages telling your program to redraw all or portions of its window as other windows are opened and closed on top of it.
This freedom from having to handle every single message from Windows is, of course, a major benefit of working in Clarion until you happen to need to see one of these messages normally filtered out by the run-time. And that, finally, is what sub-classing is all about: giving your program access to all windows messages on those occasions where you need it. Before you ask, you are not obligated to handle all those messages, as the run-time still does that. Sub-classing (and WinEvent) simply gives you the ability to selectively peek at what is happening and intercept the messages of interest to you.
Ok, enough background: let's take a look at what WinEvent is and does.
CapeSoft breaks WinEvent into five functional categories, including:
An additional bonus of the package is that the templates allow you to enable 'Auto Shut Down' in your applications by simply checking a box. If you're wondering what I mean by this, it means that your applications can shut down automatically when the user tells Windows to shut down. Currently, CW programs will stop the shutdown process and force the user to manually exit the Clarion application before Windows can be shut down.
WinEvent is distributed electronically, so it comes as a self-contained installation executable. Upon running the program, it correctly found my Clarion directory and offered to install there. I said yes, and setup proceeded to copy the WinEvent files into the appropriate subdirectories, such as \Lib, \Bin, \Examples and so forth. A WinEvent group containing a link to the documentation file was also added to my Start/Programs menu. As usual, the templates needed to be registered before they could be used.
All in all, very simple and straightforward. I do like to have the docs automatically displayed at the end of the installation process though, so that you can get up to speed with a new product as soon as possible.
As with most multiple purpose template products, the degree of difficulty in adding WinEvent to an application varies with what you want to do. Adding WinEvent itself merely requires adding a global extension template. Two options are available here, one for enabling Auto Shut Down and one for disabling all WinEvent functions. I really like the latter option, as it lets you test or implement various functions, then flip a switch and run your application as if WinEvent weren't there (without having to uninstall it). Very handy. Behind the scenes, this extension also takes care of adding the WinEvent functions to your Map and the library to your Project.
The visible effect of adding the WinEvent global extension is that every procedure with a window in your application now also has a WinEvent 'Alert Windows Messages' extension template added to it. If you don't want to use sub-classing on a particular window, just ignore it. If you do, you use the buttons shown below to specify which messages to alert and what to do about them.
You can also see that this is where you can specify whether your application should automatically shut down when Windows closes if this window has focus. Note that you have the option of enabling Auto Shut Down on some windows (such as your frame or browses) and leaving it turned off, for example, on important forms where you want to force users to complete a transaction themselves before your application can close.
The basic concept behind the WinEvent WinAlert() function is similar to the CW Alert() processing for keys. You 'alert' WinEvent to look for specific messages, then provide code to do something when the alerted message (event) occurs. You have options (which can be combined) for letting WinEvent handle the message (preventing it from ever getting to the Accept loop), passing the event through to Accept, and/or firing off a user defined Event. Template options let you specify as many messages to alert as you want, and make it relatively simple to specify what you want do when they do occur.
Note that I said relatively simple, because dealing with Windows messages is not a process for beginners. When you do need to do it, though, WinEvent takes most of the pain out of it, and does so in a manner consistent with the overall thrust of the Clarion for Windows model. All told, there are six WinEvent functions to help you with your sub-classing needs.
To continue, in the following example you can see that we would
be:
a) asking to be told when Windows issues a 'paint yourself'
message,
b) passing the message through to the Accept loop so that the
run-time will take care of repainting our window, and
c) posting an Event so that we can execute some special additional
code of our own in the Accept loop, perhaps to redraw something
using the Clarion graphics primitives or to change an image. In
other words, something not handled automatically by Clarion.

These functions help you to turn a Clarion application into a 'tray' program. Normally, these are programs that are started when Windows starts, and run constantly in the background, performing some type of service or watching for an event. In my test application, the program's job was to scan the email Inbox every 15 minutes, and take action when particular messages were received.
There are four functions related to the taskbar (each with a corresponding template to automate its use):
WinTaskBarAddIcon - Puts the icon of your choice in the tray, sets the ToolTip for the icon and returns an ID for the icon so you can refer to it later.
WinTaskBarChangeIcon - Changes the tray icon to another icon and/or resets the ToolTip, using the ID created by the 'AddIcon' function.
WinNotOnTaskBar - Removes your program from the main section of task bar, so that only the tray icon shows.
WinTaskBarRemoveIcon - Removes the icon from the tray (make sure you have made your application visible before calling this one!).
As shown in Figure 3, you have many options for which types of mouse events your tray icon can respond to. Typically, a right click pops up a menu while a double left click opens the application. You can, of course do whatever you want in response to these events.

For example, after adding this template, I put the following code into the 'Code to run when Mouse Right Up Event is received' embed point:
EXECUTE(POPUP('Restore|Hide|-|Check Now|-|Close'))
window{prop:hide} = False ! Unhide the window
window{prop:hide} = True ! Hide the window
CheckInBox ! Call InBox procedure
post(event:closeWindow) ! Shut down the app
END
Now when users right click on my tray icon, my application pops up a little menu right there and lets them choose to restore (make visible) the application, hide it, and so forth.
To help users quickly check on the status of the program, I used the WinTaskbarChangeIcon template to do two things. First, change the color of the icon (done by switching to a differently colored version of the icon) if mail had been processed, and second, changing the ToolTip to display some statistics. For example, if you hover the mouse over the tray icon, the ToolTip would display something like:
"Processed: 10, Next Scan: 11:45 AM'
All of the icon handling can be done via templates, but using the functions directly is also very simple. For example, changing the icon or its ToolTip looks like this:
WinTaskBarChangeIcon(IconID,'email2.ico','Ready to scan')
That's all there is to it.
WinEvent provides a total of ten functions related to dealing directly with a PC's Comm ports (COM1, for example). These functions let you choose a port, read and write to it, reset it, set handshaking, and check the status of various Comm lines such as carrier detect, ring, data send ready and so forth.
No templates are provided for the Comm functions. In all fairness though, if you need to be working directly with Comm ports, you will need to write code anyway. What WinEvent does is ease the task considerably by providing a simple wrapper around these complex actions.
And all the rest
In testing the rest of the package, most of the other functions needed to be implemented in source code (no templates). They are, however, very easy to use.
For example, using the 'Keep Window on Top' function to keep your program window on top of all other programs, you call it like this:
WinOnTop()
That's it. No parameters, no return value, no window handle, etc. Bringing your window to the front is just as simple.
In my testing, I found WinEvent to do everything it claimed to do. It made it easy (well, as easy as it gets) to sub-class Windows messages. The taskbar functions were simple to use and did the job without fuss. Other tests revealed the same results WinEvent simply worked.
One thing to keep in mind even though WinEvent will work in both 16 and 32 bit modes, some of the functions (such as the ones relating to the taskbar) will not work in 16-bit programs. This is not a limitation imposed by CapeSoft, however, as the Windows functions it accesses for these particular services are simply not available in 16-bit.
CapeSoft provides the WinEvent documentation as an HTML file, so it can displayed and printed easily from any Web browser (it worked out to about 19 pages when printed from Netscape). Each of the functions is well documented, and a fair amount of background is provided as well, especially on the Windows message handling functions (such as WinAlert) and Windows messaging in general. A link to it is placed on your Start/Programs menu, so it is easy to find.
On the minus side, no direct template help available. In other words, no Windows help file is provided, so pressing the 'Help' button doesn't do anything on the template screens. I didn't find this too inconvenient, though, after printing out the regular documentation.
Two example programs are provided, one that demonstrates each of the major functional groups, and one that demonstrates using the Comm and taskbar functions to create a tray program which reads barcode information via a serial port. The primary demo does a good job of illustrating how the various features of WinEvent work, as well as clearly specifying which functions you are using as you try out the various options.
As usual, CapeSoft technical support was very good. I found a few problems in the initial review version (2.4), but these were fixed and a new version (2.45) sent to me within a few days of my reporting them. As a bonus, the new version also included more options for handling mouse clicks on a taskbar icon.
As with so many products, whether or not you need a product like WinEvent depends on your need to use the specialized functionality that it provides. In my case, there is no possible way I could have implemented the desired taskbar functionality in anywhere near $30 of my time, much less write templates, easy to use wrappers, AND functions for four other nasty API tasks as well.
To sum up, I call WinEvent a useful tool set, a bargain, and recommend it highly.
| Category |
Product Score |
| Ability to do the task |
Very good |
| Ease of use |
Very Good |
| Ease of Installation |
Good |
| Documentation |
Good |
| Technical Support |
Very Good |
| Modifies Shipping Templates |
No |
| Black-Box DLLs/LIBs |
Yes |
WinEvent is $30 US for the registered version, and can be obtained direct from CapeSoft or via the TopSpeed Accessories program (1-800-354-5444). A 16-bit version is available as shareware, but lacks some of the functionality of the 32-bit version.
Versions of Clarion supported include CW 2, C4, C5EE and both the Clarion and ABC templates. More information and demos can be obtained at http://www.capesoft.com.
Copyright © 1999-2008 by CoveComm Inc. All Rights Reserved. Reproduction in any form without the express written consent of CoveComm Inc., except as described in the subscription agreement, is prohibited.
Clarion Magazine ISSN 1718-9942
One year: $184
(includes all back issues since '99)
Renewals from $134
Two years: $274
Renewals from $224