Question

J'ai une classe dérivée de CTreeCtrl . Dans OnCreate () , je remplace l'objet CToolTipCtrl par défaut par un objet personnalisé:

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;
}

Mon gestionnaire de messages ressemble à ceci:

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

Cependant, je ne reçois jamais de message TTN_NEEDTEXT . J’ai jeté un coup d’œil à Spy ++ et il semble aussi que ce message ne soit jamais envoyé.

Quel pourrait être le problème ici?

Mettre à jour

Je ne sais pas si cela est pertinent: la fenêtre parente de CTreeCtrl est de type CDockablePane . Pourrait-il y avoir du travail supplémentaire pour que cela fonctionne?

Était-ce utile?

La solution

Enfin! Je l'ai (partiellement) résolu:

Il semble que la fenêtre parent de CDockablePane ait effectivement causé ce problème ...

D'abord, j'ai supprimé tout le code spécifique à l'info-bulle de la classe dérivée de CTreeCtrl. Tout est fait dans la fenêtre du volet parent.

J'ai ensuite modifié la méthode OnCreate () de la fenêtre parente:

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;

}

Malheureusement, nous ne pouvons pas simplement appeler AddTool () avec moins de paramètres car la classe de base se plaindra sous la forme d'un ASSERT à propos d'un uFlag membre s'il n'y a pas d'ID d'outil défini. Et puisque nous devons définir l'ID, nous devons également définir un rectangle. J'ai créé un membre CRect et l'ai défini sur (0, 0, 10000, 10000) dans le CTor. Je n'ai pas encore trouvé de moyen efficace de changer la taille de l'outil, c'est donc ma solution très laide. C'est aussi pourquoi j'appelle cette solution partielle. Mise à jour: J'ai posé une question à ce sujet.

Enfin, il y a le gestionnaire pour obtenir les infos sur l'info-bulle:

// 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;
}

Autres conseils

Je pense que vous devez toujours activer l'info-bulle, même si vous remplacez le préréglage intégré.

EnableToolTips(TRUE);

Eh bien, puisque cela n’a pas fonctionné pour vous et qu’aucun autre expert n’a proposé d’aide, voici quelques suggestions supplémentaires de ma part. Bien qu'ils soient boiteux, ils pourraient vous faire bouger à nouveau:

  • Assurez-vous que votre rotation OnCreate () est en cours d'exécution.
  • Activez l'info-bulle AVANT de la remplacer.
  • Le code que j'utilise pour faire ceci ressemble à ceci. (J'avoue que je ne comprends pas tous les détails, je l'ai copié à partir d'un exemple de code, cela a fonctionné et je ne l'ai plus jamais regardé.)

    // Activer l'info-bulle standard

    EnableToolTips (TRUE);

    // Désactiver l'info-bulle intégrée

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

Je n'ai pas essayé de CTreeCtrl mais je pense que vous devriez appeler RelayEvent pour que l'infobulle ctrl indique le moment où l'info-bulle doit être affichée. Essayez ceci:

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);
}

J'espère cette aide.

Ne devez-vous pas écraser OnToolHitTest ()?

(ancienne) ressource 1

(ancienne) Ressource 2:

  

En plus de renvoyer le code d'accès (nHit), vous devez également renseigner la structure TOOLINFO. Voici comment VIRGIL le fait dans 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;

La plupart de ces opérations sont évidentes, comme le réglage de hwnd et uId & # 8212; mais certaines le sont moins. Je règle le membre rect sur un rectangle de 2 pixels de large et 2 pixels de haut, centré autour de l'emplacement de la souris. Le contrôle d'info-bulle utilise ce rectangle comme rectangle de délimitation de "l'outil". que je veux être petit, alors déplacer la souris n’importe où constituera un déplacement hors de l’outil. J'ai défini TTF _ NOTBUTTON dans uFlags car l'info-bulle n'est pas associée à un bouton. Il s'agit d'un indicateur MFC spécial défini dans afxwin.h; MFC l'utilise pour faire de l'aide pour les info-bulles. Il existe un autre indicateur étendu MFC pour les info-bulles, TTF _ ALWAYSTIP. Vous pouvez l'utiliser si vous souhaitez que le MFC affiche le conseil même lorsque votre fenêtre n'est pas active. Vous avez peut-être remarqué que, jusqu'à présent, je n'ai pas communiqué à MFC, à l'infobulle ou à TOOLINFO le texte de cette astuce. C’est ce à quoi sert LPSTR _ TEXTCALLBACK. Cette valeur spéciale indique au contrôle info-bulle (le contrôle interne global de thread que MFC utilise) de rappeler ma fenêtre pour obtenir le texte. Pour ce faire, il envoie à ma fenêtre un message WM _ NOTIFY avec le code de notification TTN _ NEEDTEXT.

Essayez de gérer spécifiquement tous les identifiants d'infobulle:

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

Si cela ne fonctionne pas, vous devrez peut-être appeler manuellement RelayEvent () à partir de PreTranslateMessage ().

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top