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 é?