Introduction
There are
times when
one would
like to
display
messages
in an
non-obtrusive
way. Message
Balloons are
one of the
new ways.
Message
Balloons
are
taking
precedence
over message
boxes for
small
display
messages as
they even
prevent the
user from
clicking an
�OK� and
still get
the message
across.
These kind
of
Message
Balloons
are
becoming a
part of
standard
user
interface
with MSN
explorer and
Windows XP.
Still no
library has
been
provided for
making these
balloons.
Hence this
attempt.
How to
use the
class
provided ?
Include
the
following
two files in
your
project:
-
BalloonTip.h
-
BalloonTip.cpp
There are
two
interfaces
to create
and show the
message
balloons.
-
CBalloonTip::Show()
-
CBalloonTip::Hide()
CBalloonTip::Show()-:
This is a
pseudo
constructor
because we
want to
force heap
creation of
the
balloon,
so that it
remains in
the memory
even after
it has been
called. It
will be
automatically
destroyed
when a it
receives a
WM_TIMER
message
which is set
in the
CBalloon::MakeVisible()
.
The other
method to
destroy the
Balloon
before the
timer ticks
is to call
the static
function
CBalloon::Hide()
.
The
constructor
for
CBalloonTip
is
protected,
hence this
helps in
forcing heap
creation.
The
following
code shows
how to
create a
Message
Balloon and
show it.
Collapse
Copy
Code
LOGFONT lf;
::ZeroMemory (&lf, sizeof (lf));
lf.lfHeight = 16;
lf.lfWeight = FW_BOLD;
lf.lfUnderline = FALSE;
::strcpy (lf.lfFaceName, _T("Arial"));
CBalloonTip::Show(
CPoint(200, 200), CSize(250, 100), _T("Please enter a password !!"), lf, 5, FALSE );
CBalloonTip::Hide()-:
This is
for
destroying
the
Balloon
for any
particular
condition
that may
arise before
it is
automatically
destroyed in
the
CBalloonTip::OnTimer()
.
Either way
if
CBalloonTip::Hide()
is
not called
the Balloon
is destroyed
in
CBalloonTip::OnTimer()
.
So the
caller (user
of this
class) does
not need to
worry about
the memory
cleanup.
Class
Design
Details
CBalloonTip
is derived
from
CFrameWnd
.
The balloon
is created
from the
combination
of two
regions, one
is a polygon
region to
show the the
Balloon
Tip
and the
other is a
Round
Rectangle
region. This
is done in
the
CBalloonTip::OnCreate()
.
Collapse
Copy
Code
int CBalloonTip::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
CRgn rgnComb;
rgnComb.CreateRectRgn(t_Rect.left, t_Rect.top, t_Rect.right, t_Rect.bottom);
int iRetComb = rgnComb.CombineRgn(&m_rgnTip, &m_rgnRoundRect, RGN_OR);
}
The
m_rgnTip
and
m_rgnRoundRect
are created
with
different
calculations
depending
upon whether
the
balloon
tip
is down or
up. The
visible
window or
balloon
region is
finally set
using
SetWindowRgn
(rgnComb.operator
HRGN(),
TRUE)
in the
CBalloonTip::OnCreate()
.
The
Balloon
window
is not shown
up in the
tucancode.netbar by
making the
Balloon a
child of an
invisible
parent in
CBalloonTip::PreCreateWindow()
This parent
window is a
member
variable (CBalloon::m_wndInvisibleParent
)
of the class
itself and
is destroyed
automatically
when the
Balloon is
destroyed.
So the
non-appearance
of the
Balloon
window in
the tucancode.net bar
is taken
care of
automatically.
Collapse
Copy
Code
BOOL CBalloonTip::PreCreateWindow(CREATESTRUCT& cs)
{
if (!::IsWindow(m_wndInvisibleParent.m_hWnd))
{
PCSTR pstrOwnerClass = ::AfxRegisterWndClass(0);
BOOL bError = m_wndInvisibleParent.CreateEx(
0,
pstrOwnerClass,
_T(""),
WS_POPUP,
0,
0,
0,
0,
NULL,
0
);
}
}
Window
Creation
The
balloon is
created with
respect from
the point
where it is
supposed to
be
displayed.
So the
calculation
of balloon
rectangle
has to be
recalculated
w.r.t. the
point at
which it is
to be shown.
Different
calculations
have to be
done if the
Balloon tip
is down or
up. This is
done in
CBalloontip::Show()
as shown
below.
Collapse
Copy
Code
CBalloonTip* CBalloonTip::Show(CPoint pt, CSize size, CString strMessage,
LOGFONT lf, UINT nSecs, BOOL bBalloonUp)
{
if (bBalloonUp)
{
nRectLeft = pt.x - (size.cx * 0.65);
nRectRight = pt.x + (size.cx * 0.35);
nRectTop = pt.y - size.cy;
nRectBottom = pt.y;
}
else
{
nRectLeft = pt.x - (size.cx * 0.35);
nRectRight = pt.x + (size.cx * 0.65);
nRectTop = pt.y;
nRectBottom = pt.y + (size.cy);
}
}
The
actual
Windows�
window
balloon
is created
in
CBalloonTip::Show()
using
Collapse
Copy
Code
pBalloonTip->Create(CRect(nRectLeft, nRectTop, nRectRight, nRectBottom));
The
CRect
passed in
the above
function
will
represent
the actual
position of
the
balloon
in screen
co-ordinates.
The timer
for the
Balloon
destruction
is set in
the next
line in
CBalloonTip::Show()
Collapse
Copy
Code
pBalloonTip->MakeVisisble(nSecs);
-
Only
one
instance
of the
Balloon
is
allowed
to
created
at a
time
using
the
static
variable
CBalloonTip::nBalloonInstances
Overview
of the demo
project
Just try
clicking the
"OK" button
without
entering
anything in
the the edit
boxes.
Compatibility
Tested
using
VC++
6 with
MFC
on Windows
2000. Should
work fine on
other
Windows
OSs(95/98/NT/ME/XP)
also, as it
uses no OS
specific
code.
The
following
changes to
the code in
the updated
version have
been made:
-
The
OnPaint
and Show
methods
have
been
updated
to do a
better
job.
-
The
message
balloon
doesn't
stay on
top of
applications
as you
switch
between
apps.
-
There is
more
rigorous
checking
to
prevent
crashes
as a
result
of null
pointers,
etc...
Conclusion
I hope
that this
contribution
will make
some
improvement
in the user
interface
code of your
forthcoming
programs!!!
Any
suggestions,
improvements
or bugs
detected are
welcome.
Enjoy...