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
indicating in any case the name
used to register. Once the payment is effective, you will receive the license key
to register the component.
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.
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...