<!-- Download Links -->
The HotSpot control constitutes a set of irregularly shaped visual elements acting as multi-state buttons.
Each of these visual elements may have several states.
Every state is characterized by its own image representation.
Left mouse button click on a particular element leads to its transition from one state to another.
Such a transition is depicted by change of element’s image from a picture corresponded to initial
state to a picture corresponded to a new state.
Click on a particular element may change not just state of this element but also state of some
other elements, according to predefined rules.
Control’s container (parent) should be notified on event of state transition.
The control may be also dynamic.
That is, control’s visual elements are able to move and/or be reshaped versus time according to predefined rules.
This modification is not caused by change in element’s state.
Dynamic visual element has different positions/images corresponding to the same state.
In this article, we present base hot spot control classes that allow developer to easily define rules
for both state transition and dynamics, and provide simple mechanism for parent notification.
Code is written in C#.
How to Use?
Two base classes for hot spot control objects are designed.
The first one,
HotSpotControl (derived from
UserControl .NET framework class), contains set of
static multi-state visual elements.
The second one,
DynamicHotSpotControl (derived from
HotSpotControl), incorporates dynamics
permitting visual elements to change their shape and position.
HotSpotLib assembly contains these classes as well as other support classes and interfaces.
The assembly consists of two files, namely, HotSpotLib.dll and DynamicHotSpotLib.netmodule.
The former contains code for static hot spot control, whereas the letter supports “dynamic extension” classes.
The DLL file contains an assembly manifest.
If your application is confined with just static hot spot control then the NETMODULE file needs not to be deployed
to an end user (although it is needed to get application built).
DynamicHotSpot control, the following steps have to be performed.
DynamicHotSpotLib namespaces are added to the References section of the project.
MyDynamicHotSpotControl class is derived from
public class MyDynamicHotSpotControl :
DynamicHotSpotControl, IHotSpotChangeState, IDynamicHotSpot
IHotSpotChangeState defines the following method to be implemented.
void ChangeStateRules() – this method defines transition between states for each visual element of a control.
Normally, it uses
HitVisualElement property of
HotSpotControl to determine visual element
clicked by left mouse button.
The property returns reference to object of
VisualElement objects of the control may be obtained with
or id (serial number) indexers.
VisualElement class provides the name and id indexers to get references to its State objects.
CurrentState property of
VisualElement class allows developer to set/get current element state.
In the sample below, two visual elements, “Beetle” and “Ground”, have two states (0 and 1) each.
Left mouse button click on “Beetle” alternates states of both elements.
Click on "Ground" causes change of state only for clicked element.
public void ChangeStateRules()
if (null != HitVisualElement)
HitVisualElement.CurrentState = (HitVisualElement.CurrentState + 1) % 2;
if ("Beetle" == HitVisualElement.Name)
this["Ground"].CurrentState = (this["Ground"].CurrentState + 1) % 2;
- The following virtual methods may be overridden (optionally).
void OnChangeState()– this method defines actions to be taken by control when one of its visual
elements is clicked.
It may be possible that no action has to be taken (default implementation) since a parent of a control
is notified separately with event/delegate mechanism (see below).
string ConstructTip(string visualElementName, string stateName) – this method constructs tip for
an element located currently under cursor.
“Bricks” for such a construction are name of visual element and name of its current state.
If method returns empty string then no tip is shown.
Default implementation returns name of visual element.
IDynamicHotSpot defines the following method to be implemented.
void DynamicsRules() – this method defines rules for movement of visual element.
It is called once on each timer tick by underlying
The sample of the method’s implementations for reciprocate movement of two objects may be found below.
private int step = 2;
public void DynamicsRules()
if (0 == TimerTicksCount)
step = -step;
this["Beetle"].X += step;
this["Ground"].X -= step;
In this sample protected get-only property
is used to synchronize objects movement.
- Constructor of
MyDynamicHotSpotControl class is designed to create all visual elements
of control and all states of each visual element.
It takes two integer parameters related to control dynamics.
The first parameter defines time interval between the two adjacent timer ticks (i.e., timer sampling interval, in ms).
The second parameter defines threshold value for timer ticks count.
Timer ticks count is reset to zero after it exceeded the threshold.
Constructor calls constructor of base class
DynamicHotSpotControl passing parameters on to it.
The sample of
MyDynamicHotSpotControl constructor is given below.
public MyDynamicHotSpotControl(int timerInterval, int timerClicksCountMax)
: base(timerInterval, timerClicksCountMax)
IHotSpotChangeStateImpl = this;
IDynamicHotSpotImpl = this;
string resourceDir = "res\\";
ActiveCursorFileName = resourceDir + "Hand.cur";
// "Ground" Visual Element
VisualElement ve0 = AddVisualElement("Ground", new Point(15, 0));
ve0.AddState("Green", resourceDir + "Ground0", "bmp");
ve0.AddState("Cyan", resourceDir + "Ground1", "bmp");
// "Beetle" Visual Element
VisualElement ve1 = AddVisualElement("Beetle", new Point(30, 0));
ve1.AddState("Image", resourceDir + "BeetleImage", "bmp");
ve1.AddState("Text", resourceDir + "BeetleText", "bmp");
References to implementation of
IDynamicHotSpot interfaces need
to be passed to ancestor object.
This is carried out using protected set-only
IHotSpotChangeStateImpl = this;
IDynamicHotSpotImpl = this;
Cursor changes its shape when left mouse button is gone down on a visual element.
New cursor shape is set with
AddVisualElement() creates new visual element using its name and location point as parameters.
VisualElement class creates a new state for visual element based
on the state name, picture file name and picture file extension.
The method finds all picture files named according to the following rule:
"picture file name" + "_" + i.ToString() ,
where i – integer serial number.
All these files are loaded, and their pictures are displayed on timer tick producing animated image of visual object
for each of its state.
- The above picture files are prepared and placed on proper path.
- Paragraphs 2 through 7 dealt with customized
MyDynamicHotSpotControl derived from
This paragraph describes code that should be added to the control’s parent form.
A new control will be created and its properties initialized probably in the parent’s constructor.
At this point a handler to the
HotSpotEvent is added.
This event is fired when left mouse button moves down and up on the same visual element (element is clicked).
Delegate for the event handler is defined in class
It takes two parameters: reference to
HotSpotControl object (source of event), and standard
Samlpe showing a fragment of parent’s constructor code is listed below.
MyDynamicHotSpotControl myDynamicHotSpotCtrl =
new MyDynamicHotSpotControl(500, 60);
myDynamicHotSpotCtrl.Name = "DYNAMIC HotSpot";
myDynamicHotSpotCtrl.Dock = DockStyle.Top;
myDynamicHotSpotCtrl.Size = new Size(0x50, 0x50);
The above procedure is addressed to dynamic hot spot control.
Usage of static version is easier.
In this case customized control is derived from HotSpotControl class and implements only
DynamicHotSpotLib namespace is not used, and
IDynamicHotSpot interface is not implemented.
Each state of a particular visual element is characterized by just one picture.
Examples of usage of both static and dynamic version of the control may be found in file Form1.cs of
accompanied sample code.
Foundation of hot spot conrol is implemented with three classes:
Actual customized control has to be derived from
interface implementing method
State characterizes each state of visual element.
It contains parameters like name, id and pictures (original picture and the same picture with transparent background).
State class checks whether mouse click was performed on non-transparent
area of its picture.
VisualElement defines each visual element of the control.
ArrayList alState of all states of a visual element.
These states are accessible outside the class through id and name indexers.
AddState() allows developer to create a new
State object and add it to alState list.
AddState() method uses internally virtual protected
StateFactory() method to create
State object or object of
HitTest() checks whether visual object was mouse clicked.
For this, it relies on
HitTest() method of current state of the visual element.
Draw() is responsible for drawing of visual element in its current state.
HotSpotControl is derived from standard .NET
It serves as base for customized hot spot control class, or, alternatively for
ArrayList alVisualElement of all visual elements
of the control.
Id and name indexers expose visual elements to outside world.
HotSpotControl handles down, up and move mouse events.
It performs hit test and draws its visual elements - both by looping through its
of visual elements.
Virtual protected methods of the class and some of its public properties are discussed in the “How to Use?” section.
HotSpotControl defines event
HotSpotEvent and appropriate delegate
This event is fired when visual element is clicked, i.e. left mouse button went down and up on the same visual element.
It is assumed that control’s parent form provides implementation for the delegate.
Foundation of dynamic hot spot control is implemented with three classes:
MultipictureVisualElement (derived from
DynamicHotSpotControl (derived from
Actual control customized by developer has to be derived from
IDynamicHotSpot interfaces implementing methods
DynamicsRules() of these
Unlike static version, in dynamic hot spot control visual elements are presented with “animated” graphic images
being in the same state.
To support this feature, class
MultipictureState accommodates several pictures,
DynamicHotSpotControl implements timer mechanism.
MultipictureState has a private class
PictureContext (containing original picture,
the same picture with transparent background and background color) and
of all picture contexts for this state.
Code sample consists of the following files. File HotSpot.cs
related classes (
namespace) and will be compiled to HotSpotLib.dll
namespace) and will be compiled to DynamicHotSpotLib.netmodule
(containing assembly manifest) and DynamicHotSpotLib.netmodule
contains sample of code consuming the controls.
It will be compiled to TestHotSpot.exe
provides compilation and runs the test.
is executable for the sample.
Test form containing dynamic and static hot spot controls is depicted below.
In the sample,
accommodates two hot spot controls, one dynamic and one static.
Each control contains three visual elements: “Beetle”, “Ground” and “Blot”.
Tip related to a “Ground” visual element of a dynamic control is seen (although cursor located just over upper-left
corner of tip area is not captured).
Click on each of visual elements leads to change in the elements’ state according to rules defined in customized control.
Static control is permanently docked to the bottom, whereas dynamic control allows docking – again, according
to rules defined by control customization.
In response to left mouse button click on a visual element, a control repaints all its visual elements in
their new states and displays two message boxes successively. The first one is emitted by customized control,
and the second one indicates call of the control’s parent change state event handler.
To change docking position of the dynamic control user should press left mouse button over any visual element and release
the button elsewhere.
Improvements and Further Development
Hot spot control presented may be improved in different ways. It may be useful in some cases to handle situation when mouse button is pressed over one visual elements and release over another. Drag-and-drop operation for visual elements within one control, or even between the controls may be supported.
Dynamics could be improved by avoiding blinking effect while repaint (well known problem which should be addressed separately), more sophisticated dynamic transformation of pictures (e.g., rotation). Adding ability to play animated GIF files is also useful.
These hot spot controls may also serve as a base and departure point for development of other types of .NET controls, like for instance, customizable toolbar control.
Static and dynamic versions of .NET hot spot control have been developed.
Its images act as multi-state buttons.
Rules for states transition and dynamics are easily customizable.
With some improvements and modifications, the control may serve as base for other controls classes.
I'd like to express here my gratitude to Stas Levin, a Windows GUI development expert (BCGSoft) and
charming Irina Zherdenovsky (Creo) for useful professional discussion.