Balão de Dicas (Tool Tip) Windows e a Taskbar
Esse estudo, mais que um artigo, é um comentário orientado para os projetos que lidam com tool tips e com a área de notificação taskbar (system tray - bandeja do sistema).
Fundamentos
Queremos mostrar o modo mais fácil de usar estes controles, porque "todo o mundo" está se queixando da falta de informação sobre este assunto. A verdade é que o MSDN não está se esforçando em explicar o uso da ferramenta dicas de balão ou como colocar o ícone da aplicação na bandeja.
Usando o código
Ao rodar, a aplicação "EasyApp" exibirá o ícone na bandeja do sistema junto com uma ferramenta dica de balão associada, tal como a aplicação padrão "Local Area Connection Status". Fazendo duplo-clique no ícone da aplicação, será mostrado o diálogo principal e passando o ponteiro do mouse por cima do diálogo, poderemos ver dicas de balão.
Clicando no botão "Minimize" a aplicação será minimizada para a bandeja, onde agora teremos dicas normais. A "mágica" acontece no objeto CEasyAppDlg. Primeiro, o membro _ToolTipCtrl; um simples objeto CToolTipCtrl MFC; é inicializado usando Create( . ):
_ToolTipCtrl.Create( this,
// o estilo do controle ToolTip
TTS_NOPREFIX | // impede o sistema
// de remover o caracter e-comercial (&)
// do string
TTS_BALLOON | // o controle ToolTip tem o aspecto de
// 0x40 // um balao com cantos arredondados
// e um “rabinho” apontando para o item
TTS_ALWAYSTIP // o ToolTip aparecerah quando o
// cursor for uma ferramenta, independentemente
// da janela dona do controle ToolTip
// estar ativa ou inativa
);
/////
(TTS_BALLOON não é parte da descricao MSDN de CToolTipCtrl::Create!)
SetÍconeAndTitleForBalloonTip( . ) o membro estah utilizando a mensagem TTM_SETTITLE para adicionar um STANDARD ICON e um string de titulo ao tool tip:
/////
BOOL CEasyAppDlg::SetÍconeAndTitleForBalloonTip(
CToolTipCtrl *pToolTipCtrl, int tti_ÍCONE, CString title )
{
return ::SendMessage( (HWND) pToolTipCtrl->m_hWnd,
(UINT) TTM_SETTITLE, // adiciona um ícone padrao e
// um string de titulo ao ToolTip
(WPARAM) tti_ÍCON,
// TTI_NONE = 0 – sem ícone
// TTI_INFO = 1 – ícone informativo
// TTI_WARNING = 2 – ícone de aviso
// TTI_ERROR = 3 - ícone de erro
(LPARAM) (LPCTSTR) title );
}
/////
Só falta passar a mensagem do mouse para ser processado pelo controle tool tip utilizando RelayEvent( . ):
/////
BOOL CEasyAppDlg::PreTranslateMessage(MSG* pMsg)
{
if( pMsg->message == WM_MOUSEMOVE )
{
_ToolTipCtrl.RelayEvent( pMsg );
}
...//etc
}
/////
Terminamos com o balão de dicas MS Windows. Para "carregar" a aplicação na bandeja do sistema, temos o membro LoadToTray local( . ), o qual usa a estrutura NOTIFYÍCONEDATA, que contém informações que o sistema necessita para processar as mensagens da área do estado do taskbar, Shell_NotifyÍcone( . ) para adicionar ou remover da área de estado do taskbar e as mensagens do usuário WM_TRAY_NOTIFY usadas para o callback:
/////
void CEasyAppDlg::LoadToTray( CWnd *pWnd,
UINT uCallbackMessage,
CString sInfoTitle, // titulo do balao ToolTip .
// este titulo eh exibido em negrito por sobre o texto
// pode ter um maximo de 63 caracteres
CString sInfo, // o texto do balao ToolTip, pode ter
// um maximo de 255 caracteres
CString sTip, // o texto do ToolTip padrao
// pode ter um maximo de 128 caracteres,
// incluindo o terminador NULL.
int uTimeout, // em segundos
HÍCON icon )
{
ZeroMemory( &_tnd, sizeof( NOTIFYÍCONEDATA ) );
_tnd.cbSize = sizeof( NOTIFYÍCONEDATA );
_tnd.hWnd = pWnd->GetSafeHwnd();
_tnd.uID = 0;
_tnd.uFlags = NIF_MESSAGE | NIF_ÍCONE | NIF_TIP | NIF_INFO;
// Descricao do Flag:
// - NIF_ÍCON O membro hicon eh valido
// - NIF_MESSAGE O membro uCallbackMessage eh valido
// - NIF_TIP o membro szTip eh valido.
// - NIF_STATE os membros dwState e dwStateMask são validos
// - NIF_INFO Usar um balao ToolTip em lugar de um ToolTip padrao
// Os membros szInfo, uTimeout, szInfoTitle e
// dwInfoFlags sao validos
// - NIF_GUID Reservado
_tnd.dwInfoFlags = NIIF_INFO;
// adicionar um ícone a um balao ToolTip
// Descricao do Flag:
// - NIIF_ERROR ícone de erro
// - NIIF_INFO ícone informativo
// - NIIF_NONE sem ícone.
// - NIIF_WARNING ícone de aviso
// - NIIF_ÍCONE_MASK Versão 6.0. Reservado
// - NIIF_NOSOUND Versão 6.0. Nao executar o
// som associado (apenas para balao ToolTips)
_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 );
}
/////
Chamamos isto em OnInitDialog(). Na função callback, o diálogo principal é redirecionado para a tela. Para remover da área de estado, no destructor (ou na saída) temos que usar Shell_NotifyÍcone(NIM_DELETE, & _tnd). Isso é tudo. Não foi tão ruim não é?