Pergunta

Eu tenho uma classe derivada de CTreeCtrl. Em OnCreate() I substituir o objeto CToolTipCtrl padrão com um personalizado:

int CMyTreeCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
    if (CTreeCtrl::OnCreate(lpCreateStruct) == -1)
        return -1;

    // Replace tool tip with our own which will
    // ask us for the text to display with a TTN_NEEDTEXT message
    CTooltipManager::CreateToolTip(m_pToolTip, this, AFX_TOOLTIP_TYPE_DEFAULT);
    m_pToolTip->AddTool(this, LPSTR_TEXTCALLBACK);
    SetToolTips(m_pToolTip);

    // Update: Added these two lines, which don't help either
    m_pToolTip->Activate(TRUE);
    EnableToolTips(TRUE);

    return 0;
}

A minha mensagem manipulador esta aparência:

ON_NOTIFY_EX(TTN_NEEDTEXT, 0, &CMyTreeCtrl::OnTtnNeedText)

No entanto eu nunca receber uma mensagem TTN_NEEDTEXT. Eu tinha um olhar com Spy ++ e também parece que esta mensagem não é enviada.

O que poderia ser o problema aqui?

Atualização

Eu não tenho certeza se isto é relevante: janela pai do CTreeCtrl é do tipo CDockablePane. Poderia haver algum trabalho extra necessário para este trabalho?

Foi útil?

Solução

Finalmente! I (parcialmente) resolveu:

Parece que a janela pai CDockablePane fato causou este problema ...

Em primeiro lugar eu removi todo o código específico do dica da classe CTreeCtrl derivado. Tudo é feito na janela do painel pai.

Então eu editei método OnCreate() da janela pai:

int CMyPane::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
    if (CDockablePane::OnCreate(lpCreateStruct) == -1)
        return -1;

const DWORD dwStyle = WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN |
    TVS_CHECKBOXES | TVS_DISABLEDRAGDROP | TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT |
    TVS_INFOTIP | TVS_NOHSCROLL | TVS_SHOWSELALWAYS;

// TREECTRL_ID is a custom member constant, set to 1
if(!m_tree.Create(dwStyle, m_treeRect, this, TREECTRL_ID ) )
{
    TRACE0("Failed to create trace tree list control.\n");
    return -1;
}

// m_pToolTip is a protected member of CDockablePane
m_pToolTip->AddTool(&m_tree, LPSTR_TEXTCALLBACK, &m_treeRect, TREECTRL_ID);
m_tree.SetToolTips(m_pToolTip);


return 0;

}

Unforunately não podemos simplesmente chamar AddTool() com menos parâmetros porque a classe base vai reclamar na forma de um ASSERT sobre um membro uFlag se não houver nenhum conjunto de ferramentas ID. E uma vez que precisamos para definir a ID, que também precisa definir um retângulo. Eu criei um membro CRect e configurá-lo para (0, 0, 10000, 10000) no ctor. Eu ainda não encontrou uma maneira trabalhando para mudar o tamanho rect da ferramenta de modo que este é o meu solução muito feio. É também por isso que eu chamo esta solução parcial. Update: Eu fiz uma pergunta em relação a este

Finalmente, há o manipulador para obter a informação dica:

// Message map entry
ON_NOTIFY(TVN_GETINFOTIP, TREECTRL_ID, &CMobileCatalogPane::OnTvnGetInfoTip)


// Handler
void CMyPane::OnTvnGetInfoTip(NMHDR *pNMHDR, LRESULT *pResult)
{
    LPNMTVGETINFOTIP pGetInfoTip = reinterpret_cast<LPNMTVGETINFOTIP>(pNMHDR);

    // This is a CString member
    m_toolTipText.ReleaseBuffer();
    m_toolTipText.Empty();

    // Set your text here...

    pGetInfoTip->pszText = m_toolTipText.GetBuffer();

    *pResult = 0;
}

Outras dicas

Eu acredito que você ainda tem que permitir que a dica de ferramenta, mesmo que você está substituindo o builtin.

EnableToolTips(TRUE);

Bem, uma vez que não funcionou para você e uma vez que ninguém mais experiente ofereceu qualquer ajuda, mais aqui algumas sugestões de mim. Embora eles são coxos, eles podem levá-lo a se mover novamente:

  • Verifique se o seu OnCreate () em rotina que realmente está sendo executado.
  • Ative a ponta ferramenta antes de substituí-lo.
  • O uso de código eu fazer isso se parece com isso. (Confesso que não entendo todos os detalhes, eu algo copiado de um código de exemplo, funcionou e então eu nunca olhei para ele mais.)

    // Ativar a dica de ferramenta padrão

    EnableToolTips (true);

    // Desativar o builtin dica

    CToolTipCtrl * pToolTipCtrl = (*) CToolTipCtrl CWnd :: FromHandle ((HWND) :: SendMessage (m_hWnd, LVM_GETTOOLTIPS, 0, 0D));

Eu não tentei em um CTreeCtrl mas eu acho que você deveria chamar RelayEvent para o ctrl dica para saber quando a dica de ferramenta tem de ser exibido. Tente isto:

MyTreeCtrl.h:

virtual BOOL PreTranslateMessage(MSG* pMsg);

MyTreeCtrl.cpp:

BOOL CMyTreeCtrl::PreTranslateMessage(MSG* pMsg) 
{
    m_pToolTip.Activate(TRUE);
    m_pToolTip.RelayEvent(pMsg);

    return CTreeCtrl::PreTranslateMessage(pMsg);
}

Espero que isso ajuda.

Você não tem que substituir OnToolHitTest ()?

(old) Resource 1
(old) Recurso 2:

Além de retornar o código de sucesso (Nhit), você também tem que preencher a estrutura TOOLINFO. Veja como VIRGIL faz em CMainFrame :: OnToolHitTest:

 int nHit = MAKELONG(pt.x, pt.y);
 pTI->hwnd = m _ hWnd;
 pTI->uId  = nHit;
 pTI->rect = CRect(CPoint(pt.x-1,pt.y-1),CSize(2,2));
 pTI->uFlags |= TTF _ NOTBUTTON;
 pTI->lpszText = LPSTR _ TEXTCALLBACK;

A maioria deles é óbvia-like definição hwnd e uId, mas algumas delas são menos. I definir o membro rect a uma ampla-2-pixel, dois pixels de altura rectângulo centrado em torno da localização do rato. O controle dica de ferramenta usa este retângulo como o retângulo delimitador da "ferramenta", que eu quero ser pequena, portanto, movendo a qualquer lugar do mouse se constituem em movimento fora da ferramenta. I definir TTF _ NOTBUTTON em uFlags porque a dica de ferramenta não está associada a um botão. Esta é uma bandeira MFC especial definido no afxwin.h; MFC usa para fazer ajuda para dicas de ferramentas. Há uma outra bandeira MFC-estendida para dicas, TTF _ ALWAYSTIP. Você pode usá-lo se você quiser MFC para exibir a ponta, mesmo quando a janela não está ativo. Você deve ter notado que até agora eu não contei MFC ou a dica de ferramenta ou o TOOLINFO que o texto real da ponta é. Isso é o que LPSTR _ TEXTCALLBACK é para. Este valor especial informa o controle dica de ferramenta (o, um interno thread-global que usa o MFC) para chamar minha janela de volta para obter o texto. Ele faz isso através do envio de minha janela um WM _ NOTIFICAR mensagem com TTN código de notificação _ NeedText.

Tente lidar especificamente todos os ids dica:

ON_NOTIFY_EX_RANGE(TTN_NEEDTEXT, 0, 0xFFFF, &CMyTreeCtrl::OnNeedTipText)

Se isso não funcionar, você pode ter que chamar manualmente RelayEvent () de PreTranslateMessage ().

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top