Introduction

The right hand of the Windooze's taskbar (where you can see the time) is the status zone. There, you may see one or more icons, known as notification icons. The program that put them there, may be running in the background or waiting for an event to occur. When the pointer of the mouse is located over a notification icon, all of its events will be notified to its 'parent' program. If you let the pointer stay for a while in that position, a popup text will appear indicating (normally) the status of the application or some other relevant information. When an event of the mouse occurs over that icon, its parent will come to the foreground, or will show a list of possible options, or whatever. For instance, if you are the fortunate owner of a laptop, you will see an icon indicating if the computer is plugged or not and, in this case, the status of the battery charge.

With AxITray your application will be able to show notification icons capable of the following operations:

- show the application's main window
- hide it
- close the application
- access every menu of your program
- show a help window

With them and changing the icon and the popup text, you would find lots of possibilities.

You may think... Is this functionality useful? How can my program use it? Your application may offer special options or menu quick access through a notification icon; it may be running background task reporting us of its status or the disposability of data changing the icon...

Properties and functions

In the samples of using functions I assume the VB. language, supposed that the control has been attached to the project through the Components option of the Project menu, and named it AxITray1.

Properties

You have two property pages where to establish the control's default settings. In the first one, you can define the icon and tip text of the notification icon. In the second one, the events that will be notified to the application from the taskbar, and which operation will be associated to each event. You have a CheckBox and a ComboBox per event, where you can indicate if the event must be notified or not and the associated operation.

You can define all possible combinations, except uncheck the mouse left click.

In the properties window (if you are using VB.) you will see two properties named "TipText" and "Operation". The "TipText" property will modify the popup message shown by the notification icon. The "Operation" property modifies the operation when clicked the left button of the mouse. You can modify them there or in the property pages. You can also modify them when executing the program.

All the other properties, can only be modified in these property pages.

Except the left button click, you cannot modify (when executing) the operation assigned to a mouse event. But, if the assigned operation to such event is to show a menu, you can modify the menu to be shown through a function.

You can also modify the notification icon (when executing) through a function.

General functions

SetHandleWnd

Use this function to indicate to the control the handle of the window. The control will send notification messages to this window. Call this function first. (see note).

C Format void SetHandleWnd(long hwnd)
VB. Format SetHandleWnd (hwnd As Long)

- hwnd will be the handle of the window that will 'own' the icon.

This function does not return a value.

p.e: AxITray1.SetHandleWnd Me.hWnd GetLastErrorString

ShowTray and SetPopupMenu functions return a boolean value (True or False) indicating the result of its operation. If a function returns ‘False’ it cannot complete its execution (it was called with a parameter out of range, for instance). Calling this function you can obtain a string with the last error produced.

C Format BSTR GetLastErrorString()
VB. Format GetLastErrorString() As String

This function does not take parameters.

It will return a string containing the description of the last error detected. Once the error string is returned, it will clear the error.

p.e: Dim sError as String
If NOT (AxITray1.ShowTray(NIM_ADD,Image1.Picture) ) Then
‘ we've got an error
sError = AxITray1.GetLastErrorString()
MsgBox sError
End If
Notification functions

SetPopupMenu

One of the operations you can define for a mouse event is to show one of your program's menu as a popup menu. For that, the control needs the handle of that menu to show.

C Format BOOL SetPopupMenu(short nButton, long handleWnd, short nIndex)
VB. Format SetPopupMenu(nButton As integer, handleWnd As Long, nIndex As Integer) As Boolean

- nButton will be the mouse button to which associate the menu within the range from 0 to 5; 0 will be left button click, 1 left button double click, and so on (see constants vs. parameters).

- handleWnd handle of the window that owns the menu. If is the same window indicated to the function SetHandleWnd, it must be 0.

- nIndex position of the menu in the menu bar of the window (this position is zero based; 0 is the first menu, 1 the second, and so on).

If there is an error retrieving a menu handle it will return ‘False’, otherwise ‘True’.

p.e: If NOT (AxITray1.SetPopupMenu(4, frmMenus.hWnd, 2)) Then ...
ShowTray

It shows, modifies or hides the notification icon in the taskbar. The modify operation can change the icon, the tip text and, if previously changed, the menus associated to the mouse events.

C Format BOOL ShowTray(long dwAction, long hIcon)
VB. Format ShowTray(dwAction As Long, hIcon As Long) As Boolean

- dwAction operation to do: 0 show, 1 modify and 2 hide (corresponding to system constants NIM_ADD, NIM_MODIFY, and NIM_DELETE (see constants vs. parameters).

- hIcon indicates, optionally, the handle of the icon to show. When not needed must be 0; the control will show the icon defined in the property pages.

If there is an error it will return ‘False’, otherwise ‘True’.

p.e: AxITray1.SetHandleWnd Me.hWnd
Dim sError as String
If (AxITray1.SetPopupMenu (4, frmMenus.hWnd, 2)) Then
If NOT (AxITray1.ShowTray (1, Image1.Picture)) then
sError = AxITray1.GetLastErrorString()
MsgBox sError
Exit Sub
End If
Else ...

In this example AxITray.ShowTray (1, Image1.Picture) will return 'False' because we are trying to modify the icon in the taskbar, which has not be shown. We need to show it first...

If NOT (AxITray1.ShowTray (0, 0)) then... Tips and tricks

Compile your program in native mode, not only for better performance, but also to avoid problems of violation access with the VB. IDE libraries.

All functions need the handle of the window to which send messages. The function that indicates to the control which window use is SetHandleWnd. Call it first. I suggest calling it in the form loading event.

The most interesting operation you can define for a mouse event is the ability to show up to six menus retrieved from the application, accessing all their options. But, when you choose some of these options from the popup menu, the associated code will be executed in the application's primary thread. Don't select menu options that launch large processes, for they lock the application until they terminate. Use this functionality to check the behavior or appearance of the application.



Constants vs. parameters

Functions receiving an integer or long integer as a parameter indicating the operation requested, may be called with a number.

AxITray1.ShowTray (0, 0)

install the 'notification icon' showing its default icon.

AxITray1.SetPopupMenu (1, 0, 2)

show the third menu of the window which handle was passed to SetHandleWnd when double clicked the left mouse button.

You can work with long integers if you want, but you will it find more accurate to define constants and work with them, for instance:

Private Const nShowIcon As Long = &H0
Private Const nDefaultIcon As Long = &H0
Private Const nLeftDblClk As integer = &H1
Private Const nDefaultWindow As Long = &H0
Private Const nFirstMenu As integer = &H0

Now you can call the functions as

AxITray1.ShowTray (nShowIcon, nDefaultIcon) 
AxITray1.SetPopupMenu (nLeftDblClk, nDefaultWindow, nFirstMenu + 2)

If you prefer using constants in function calls, define the following naming them as you want:

Calling ShowTray

Private Const nShowTray As Long = &H0
Private Const nModifyTray As Long = &H1
Private Const nHideTray As Long = &H2
Calling SetPopupMenu

Private Const nLeftClick As Integer = &H0
Private Const nLeftDblClick As Integer = &H1
Private Const nMiddleClick As Integer = &H2
Private Const nMiddleDblClick As Integer = &H3
Private Const nRightClick As Integer = &H4
Private Const nRightDblClick As Integer = &H5

SetPopupMenu | ShowTray


Known problems

Property pages

When working with the property pages you will see in the properties window of VB. (if you are working with it), that changing from one or another means automatic validation of the properties set in the first one, as the Apply button was clicked. In fact, this is what happens. This is normal. When synchronizing the contents between the property pages and the properties window, and vice versa, we have two possibilities: to notify immediately the change or not. In the first case, the mere fact of selecting another property page implies properties validation between the two containers. In the second, properties are validated pushing on the Apply or the Ok buttons, but you would still see in the properties window the unchanged values, making necessary 'to force' this container to reload the properties, selecting another control, and re-selecting the previous again.

In both cases the properties are correctly validated, but in the second we may think that we didn't validate the properties, repeating the process. For this reason I consider this approach less efficient.

Accessing a menu

In the previous sample, we access to a menu of a form not loaded and that will never be shown. It's a 'Joker' form, only used to get access to its menu. Its options may be implemented in it, or simply call another's form functions. It seems to be more efficient placing that menu in the main form and setting its 'Visible' attribute to 'False', in order to prevent it to be shown, instead of creating a new form only for its design. As a general rule, this is better. But if you want to show a menu not visible through AxITray, this method won't work.

The reason is that AxITray retrieves a menu through its handle, that won't be valid if the menu is not accessible; if the menu is not visible or is not enabled, this handle points to an object not enabled that AxITray could not show. If you need a menu that will never be shown, except through a notification icon, this is the way.

For the same reason, if you unload the 'Joker' form and then try to show its menu you will see... nothing, because the handle points to a not existing object.

Unknown problems

This section wouldn't be necessary if we (the programmers) were perfect but as that is not the case we must consider that something may not work correctly.

If you detect some problem working with AxITray, please send me your comments about the anomaly (describing it as well as possible), to kikusi@arrakis.es indicating something as "Bug detected" or similar.

Before letting me know about an error, check if it is also produced with your program compiled in native mode. It's possible that if it is running within the VB. IDE or compiled as interpreted code (p-code), it may have problems with some VB. library.

Ordering info

I'm not going to tell you what shareware is, if you want you can read the article about shareware at the end of this file. But I'll tell you some considerations about my point of view.

First of all, when designing this control, I was thinking about making use of certain interesting characteristics (only accessible calling the Windooze API) of the 'modern' systems easy. I think you will find it useful and easy to handle, though the utility I assume it has, other people may find it not very useful or simply not adequate to its purpose.

It took me some time and some work until I got satisfied with the performance and accuracy of a component I hope will help you in your developments. 

Secondly, programming is not my only occupation (really, I'm a carpenter), so I must get some kind of compensation for the work I take, and the hours of 'suffering' that my family have to bear with.

I don't like sharing components with unavailable characteristics or time limitation, so AxITray is totally functional. But I think that if someone gets registered, he must obtain some benefit, despite the little it may be. In this case, the only advantage for registered users (apart from contribute supporting the shareware philosophy) is the removal of the copyright window.

To order, mail me to kikusi@arrakis.es or the mailing address below, indicating the following data:

Name wanted in the license registration (commercial or particular).
Mail address (eMail).
Number of licenses (when not indicated, I will assume 1).
Don't forget to indicate the control to register (AxITray).

Payments must be in EEC (CEE) euros or US dollars, made by international postal money order or by check payable to:

Miguel Perancho Hevia
San Bartolomeo da Freixa
32514 - Boborás, Ourense
Spain

or (preferred) by bank draft to the account nº:

2038-4028-57-6000036475

indicating in any case the name used to register. Once the payment is effective, you will receive the license key to register the component.

Pricing list:

AxITray, particular developers -> 12,25 euros, US $ 13.00
AxITray, educational institutions -> Contact me for special pricing
AxITray, corporations -> Contact me

For more information or to download click here.

También en castellano.

Samples

I have included some samples written in VB. You can find them in the Samples folder.

Don't expect amazing things, they are only intended to illustrate the control's basic functionality. I hope you find them useful.

About shareware

Not long ago, we had to buy commercial programs totally 'blind', evaluating the product after purchasing it. Today, as a previous step of the final product being released, it's very common that we have the chance to test a pre-release, 'Demo' or 'Beta', limited its use to not all of its characteristics or with time limitation, for evaluation purposes. The shareware is quite responsible of this fact.

The time when shareware or freeware programs were worse software solutions has gone, as an example, evaluate any shareware design program that you can probably install from that cd-rom that comes along with your favorite magazine.

As you will know, the philosophy on which shareware is based is ‘try before buy’. So, a user can test the excellence (or its absence) of the software before taking the decision of purchasing it. And, normally, there is less money required. It's true (but not always) that a single programmer, or little group of them, cannot compete against a team formed by many persons and millionaire resources, developing complex projects. But, in the other hand, he may offer us other solutions (components, plug ins or programs) these teams don't care about.

Us, those who stay hours and hours sitting in front of (the evil) the computer, occasionally realize that a marvelous program, which occupies over 200 'tasty' megs of our disk and does lots of 'well done' things, lacks a little detail which will make our work simplier or more efficient, and someone (somewhere in the world) has found a way to solve this detail, offering his solution to us, changing its dedication to it somehow.

Shareware is based in the confidence a developer of an utility which saves some of our time has in we will compensate his efforts. It's not unusual to find those who only ask for a letter making them know who we are, where we are and what we think about their work, though the most usual, and in this case I have decided so, is an economic compensation.

This is shareware. I offer something you can take and try on your own. If you, after evaluating, decide to use its functionality, you must accept the conditions under which I offer it.

All this means nothing without the support of the users. If nobody gets registered, the programmer will give up developing, and we will be left in the hands of a few. The advantages (for you) supporting shareware are obvious: you will have thousands of software solutions against (generally more expensive, though generally also more complete) 'commercial' software.

But, al least you will have the chance to select from many possibilities, not from only a few.

Now, it's your decision...



The author (or the one to blame)

For more information or to download click here.