MSN Messenger Type Task Bar Message Box
Environment: VC++ 6.0, VC++ .NET Beta 2, Windows 2000
Introduction
There are times when you want to make messages pop up in an unobtrusive way and display messages to the user without interrupting him with dialog boxes.
This article shows you the source code about making a pop up message window like MSN Messenger.
Include the following files in your project.
- TaskBarMsgWnd.h
- TaskBarMsgWnd.cpp
Following lines show how to create an object of CTaskBarMsgWnd
and use it to pop up a window. We use a pseudo constructor called CreateObject() because we want to force
heap creation. For making the normal constructor unavailable we make it
"private". We want to make the object on the heap because the PopMsg()function will trigger timers and
animate the poping up and collapsing of the window even after it has
returned. So the message window should remain in memory till all timers
subside and the window collapses. This even makes the parent application and the window's thread
more responsive than using Sleep()API which was used earlier. Using Sleep() made the thread block till
the window got destroyed.
CTaskBarMsgWnd* t_MsgWnd = CTaskBarMsgWnd::CreateObject(
_T("Some idiot has signed in !!"),// the message to be displayed
180, // width of the window
150, // height of window
4000, // time in milliseconds for the message to be displayed
10, // delay for animation, how fast the window opens
// and closes in milliseconds
CRect(30, 30, 130, 110), // rectangle in the window where the
// message will be displayed
RGB(120, 0, 0), // Color of the background
RGB(255, 255, 255) // Color of the text
);
t_MsgWndMsg->PopMsg();
Creation of Window in Separate Thread
The earlier version of this article created the message window in the same thread. Hence there were some performance hits because the main window was not much responsive to user inputs like menu selections, window drag, window resize etc.
In this updated version of article we will create the message window in a separate thread. Out of the two threads provided by MFC we chose the user interface thread creation. Create a new class called CPopWndThread derived from CWinThread..Override the InitInstance() of this thread as shown below
BOOL CPopWndThread::InitInstance()
{
m_pMainWnd = CTaskBarMsgWnd::CreateObject(
_T("Some idiot has signed in !!"),
180,
150,
3000,
1,
CRect(30, 30, 130, 110),
RGB(120, 0, 0),
RGB(255, 255, 255)
);
CTaskBarMsgWnd* pMsgWnd = (CTaskBarMsgWnd*)m_pMainWnd;
pMsgWnd->PopMsg();
return TRUE;
}
The thread and the associated window are destroyed automatically when the message window collapses in the OnTimer() function of CTaskBarMsgWnd using DestroyWindow() and PostQuitMessage() to exit the thread.
Creation of Thread
The separate user interface thread is created in the CMainFrame::OnMessagePop() using the following code,
void CMainFrame::OnMessagePop()
{
::AfxBeginThread(RUNTIME_CLASS(CPopWndThread));
}
Animation Details
The PopMsg() function first checks where the Task Bar is on the desktop. There are only four cases
- Task Bar at the bottom of the screen.
- Task Bar at top of the screen.
- Task Bar at the left of the screen.
- Task Bar at the right of the screen.
The follwing code of PopMsg() function shown
void CTaskBarMsgWnd::PopMsg()
{
if (CheckIfTaskBarBottom()) // Most frequent case is status
// bar at bottom
{
PopWndForBottomTaskBar();
}
else
{
if (CheckIfTaskBarTop())
{
PopWndForTopTaskBar();
}
else
{
if (CheckIfTaskBarLeft())
{
PopWndForLeftTaskBar();
}
else
{
PopWndForRightTaskBar();
}
}
}
}
The CheckIfTaskBarBottom()(or
CheckIfTaskBarTop(),
CheckIfTaskBarLeft())functions use
GetSystemMetrics() and SystemParatmeterInfo()
APIs to calculate the full screen area and the area on the screen minus
the status bar. Then with some elementary high school mathematics we
calculate where exactly the status bar is(bottom, top, left or right) and
appropriately show the message window with some animation.
The real action occurs in the OnTimer() function which
gets triggered because of WM_TIMER messages. There are three timers
- IDT_POP_WINDOW_TIMER -> Gets triggered for animating
popup
- IDT_SHOW_WINDOW_TIMER -> Gets triggered for showing and
keeping the window in position for some time
- IDT_COLLAPSE_WINDOW_TIMER -> Gets triggered for animating window collapse
There are three other constants namely STP_BOTTOM,
STP_TOP, STP_RIGHT and STP_LEFT which represent where
the status bar position is. These are used in OnTimer() for
the appropriate animation calculations.
The window is automatically deleted after collapsing in the
OnTimer() function using CWnd::DestroyWindow().
That's the reason we force this window's creation on heap
Class Details
The class CTaskBarMsgWnd is derived from CFrameWnd. The title bar is
removed int the follwing code in the OnCreate() member
function.
CFont objects are created, one underlined
font and the other non-underlined. We show the underlined font when mouse
is above the window using OnMouseHover() function (for
WM_MOUSEHOVER message). Similarly we use the non-underlined font when the
mouse leaves the window with OnMouseLeave() function (for
WM_MOUSELEAVE message). Initialize a "hand" cursor m_hCursor
for showing the mouse when it is over the window.
Rewrite the OnLButtonDown() for the WM_LBUTTONDOWN message
to suit any thing you would like to do...!!!!. At this point
OnLBottonDown() only shows a message box. You can change and
do anything to suit your needs.
int CTaskBarMsgWnd::OnCreate( LPCREATESTRUCT lpCreateStruct ) { if (CFrameWnd::OnCreate(lpCreateStruct) == -1) return -1; ModifyStyle(WS_CAPTION, 0, SWP_FRAMECHANGED); // removes title bar // Start creating two fonts, one underlined , other non underlined // // LOGFONT structure for font properties LOGFONT lf; ::ZeroMemory (&lf, sizeof (lf)); lf.lfHeight = 100; lf.lfWeight = FW_BOLD; lf.lfUnderline = TRUE; ::strcpy (lf.lfFaceName, _T("Arial")); // Prepare for an underlined font m_fontMessageUnderline.CreatePointFontIndirect(&lf); // Prepare an non undelined font lf.lfUnderline = FALSE; m_fontMessageNoUnderline.CreatePointFontIndirect(&lf); // Initialize the cursor. m_hCursor = ::LoadCursor(NULL, IDC_HAND); return 0; }
Downloads
Download demo project - 22 KbDownload source - 7 Kb

Comments
MSN Messenger Type Task Bar Message Box
Posted by vijayevol on 06/08/2006 10:09amgood
-
ReplyyeS
Posted by SophieyaCDJ on 12/28/2007 08:27pmGOOD
Replysource code links
Posted by zephyrer on 10/18/2005 10:56pmhttp://www.codeguru.com/code/legacy/statusbar/StatusBarMsgWnd_src.zip and http://www.codeguru.com/code/legacy/statusbar/StatusBarMsgWnd_demo.zip
ReplyLink for code does not work.
Posted by on777 on 07/22/2004 12:13am-
Reply^^
Posted by kch1001 on 04/08/2005 01:19pm6
ReplyI can't download source code!!!
Posted by shen on 06/30/2004 01:06pmCould you fix the link????
-
-
ReplyI can't download source code!!!
Posted by rajatgogri on 09/24/2005 04:54amfix the link
ReplyI also cold not download the source as well as demo.
Posted by johnblr on 11/19/2004 03:03amPlease fix the link
ReplySolution to focus loss
Posted by Legacy on 04/08/2003 12:00amOriginally posted by: Carles
The response of Catteral is good.
But the problem is that the focus is loss when the windos is created.
To solve it, add this line:
SetWindowPos(&wndTopMost,m_nWndLeft,m_nWndBottom - m_nWndSize -5,m_nWndWidth - 10,m_nWndSize,SWP_SHOWWINDOW|SWP_NOACTIVATE);
in the ::OnCreate function.
And add SWP_SHOWWINDOW|SWP_NOACTIVATE to all SetWindowPos of the code.
Bye.
ReplyA nice one !!!
Posted by Legacy on 01/28/2003 12:00amOriginally posted by: Mahesh Varma
ReplyA very good work.
Rob Catteral! Tip doesn't work
Posted by Legacy on 11/06/2002 12:00amOriginally posted by: Saeed A. Siddiqui
Mr. Catteral the tip you given at 22/11/2002 doesn't work.
Plz send some more tips if u know.
Thank You.
ReplyWhy does it not work with a modeless dialog ?
Posted by Legacy on 09/03/2002 12:00amOriginally posted by: yakov
I use the same code but I write m_pTVDlg = new CTVDlg in my InitInstance and the CTVDlg inharits CDialog and creates modeless dialog from resource.
For some reason it hangs on the dialog creation.
It worked perfect when CTVDlg was created on the main thread.
Any ideas?
Thanx in advance,
ReplyYakov
Memory leak
Posted by Legacy on 03/01/2002 12:00amOriginally posted by: Weiye
When i run your program, i found out there are memory leaks when the main application is closed before the pop window fully shows itself. It points to these 2 lines, according to the debugger
CTaskBarMsgWnd* t_TaskBarMsgWnd = new CTaskBarMsgWnd(
strMsg,
nWndWidth,
nWndHeight,
nMsgTimeOut,
nMsgWndCreationDelay,
rectMsgRect,
clrBox,
clrText
);
and
IMPLEMENT_DYNCREATE(CPopWndThread, CWinThread)
Do you have any solution to this?
ReplyWindow Z Order
Posted by Legacy on 12/03/2001 12:00amOriginally posted by: Seenu Upadhya
ReplyLoading, Please Wait ...