Introduction
I will not call this an article but rather a comment to all projects that are dealing with balloon tool tips and taskbar notification area (system tray).
Background
I want to show the easiest way to use these controls because "everybody" is complaining about the lack of information on this issue. What is true is that MSDN is not excelling in explaining how to use a balloon tool tip or how to load your application into the tray.
Using the code
My "EasyApp" application on run will display its icon into the system tray with a balloon tool tip associated just like "Local Area Connection Status" standard application. On application icon double click the main dialog will be shown and with mouse over the dialog controls we can see balloon tool tips. By clicking on "Minimize" button the application will be "minimized" into the tray where now we have a regular tool tip. The "magic" is happening inside the CEasyAppDlg
object. First the _ToolTipCtrl
member, which is a simple CToolTipCtrl
MFC object, is initialized using Create( . )
:
_ToolTipCtrl.Create( this,
TTS_NOPREFIX |
TTS_BALLOON |
TTS_ALWAYSTIP
);
(
TTS_BALLOON
is not part of the
CToolTipCtrl::Create
MSDN description!)
SetIconAndTitleForBalloonTip( . )
local member is using TTM_SETTITLE
message to add a STANDARD ICON and title string to the tool tip:
BOOL CEasyAppDlg::SetIconAndTitleForBalloonTip(
CToolTipCtrl *pToolTipCtrl, int tti_ICON, CString title )
{
return ::SendMessage( (HWND) pToolTipCtrl->m_hWnd,
(UINT) TTM_SETTITLE,
(WPARAM) tti_ICON,
(LPARAM) (LPCTSTR) title );
}
The only thing left is to pass the mouse message to the tool tip control for processing using
RelayEvent( . )
:
BOOL CEasyAppDlg::PreTranslateMessage(MSG* pMsg)
{
if( pMsg->message == WM_MOUSEMOVE )
{
_ToolTipCtrl.RelayEvent( pMsg );
}
...
}
It is done with the MS Windows balloon tool tip. Over :-)
To "load" the application into the system tray I have a local member LoadToTray( . )
that is using NOTIFYICONDATA
structure, which contains information that the system needs to process taskbar status area messages, Shell_NotifyIcon( . )
to add or delete to the taskbar's status area and WM_TRAY_NOTIFY
user defined message used for callback:
void CEasyAppDlg::LoadToTray( CWnd *pWnd,
UINT uCallbackMessage,
CString sInfoTitle,
CString sInfo,
CString sTip,
int uTimeout,
HICON icon )
{
ZeroMemory( &_tnd, sizeof( NOTIFYICONDATA ) );
_tnd.cbSize = sizeof( NOTIFYICONDATA );
_tnd.hWnd = pWnd->GetSafeHwnd();
_tnd.uID = 0;
_tnd.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP | NIF_INFO;
_tnd.dwInfoFlags = NIIF_INFO;
_tnd.uCallbackMessage = uCallbackMessage;
_tnd.uTimeout = uTimeout * 1000;
_tnd.hIcon = icon;
strcpy( _tnd.szInfoTitle,sInfoTitle );
strcpy( _tnd.szInfo, sInfo );
strcpy( _tnd.szTip, sTip );
Shell_NotifyIcon( NIM_ADD, &_tnd );
}
We just call this into
OnInitDialog()
. On callback function the main dialog is "restored" to the screen. Into the destructor (or on exit) we have to use
Shell_NotifyIcon( NIM_DELETE, &_tnd )
to delete from the status area. That�s it. Was not that bad wasn�t it? I know that I plagiarize MSDN and I apologize :-) Good luck! Liviu Birjega