1

Is it possible to add a custom tooltip on a CMFCToolBarComboBoxButton in a CMFCToolbar ?

I can now use the "default" tooltip text as defined in the resource file, but I cannot find the way to be able to dynamically change the tooltip text on the combobox in the toolbar.

Resources :

IDR_TOOLBAR1 TOOLBAR 16, 15
BEGIN
  BUTTON      ID_BUTTON32771
  BUTTON      ID_BUTTON32772
  BUTTON      ID_BUTTON32773
END

STRINGTABLE
BEGIN
  ID_BUTTON32771 "Button 1\nButton 1"
  ID_BUTTON32772 "Button 2\nButton 2"
  ID_BUTTON32773 "Button 3\nButton 3"
END

Toolbar is created normally and is showing up nicely; I "replace" the button with a CMFCToolBarComboBoxButtoncsCombo in OnToolbarReset (handler of AFX_WM_RESETTOOLBAR )

LRESULT CMainFrame::OnToolbarReset(WPARAM wp,LPARAM)
{
  UINT uiToolBarId = (UINT) wp;
  if (uiToolBarId == IDR_TOOLBAR1 )
  {
    CMFCToolBarComboBoxButtoncsCombo(ID_BUTTON32772, GetCmdMgr()->GetCmdImage(ID_BUTTON32772, FALSE), CBS_DROPDOWNLIST);

    m_MyToolbar.ReplaceButton(ID_BUTTON32772, csCombo);
    m_MyToolbar.AddItem( _T("un") );
    m_MyToolbar.AddItem( _T("deux") );
    m_MyToolbar.AddItem( _T("trois") );

  }

  return 0;
}

This work fine, the button is replaced with the combobox and the default tooltip text is displayed.

Now, I want to be able to have the tooltip text changed dynamically.

I tried to handler TTN_NEEDTEXT (and TTN_NEEDTEXTA and TTN_NEEDTEXTW) in the main frame (and even in my derived toolbar class), but it is not called for the toolbars.

I tried deriving my own CMFCToolBarComboBoxButton class and override the 2 virtual methods I could find that should be doing what I expected :

class MyComboBox : public CMFCToolBarComboBoxButton
{
public:
  MyComboBox ();
  MyComboBox (UINT uiID, int iImage, DWORD dwStyle = CBS_DROPDOWNLIST, int iWidth = 0);

  virtual BOOL OnGetCustomToolTipText(CString& );
  virtual BOOL OnUpdateToolTip(CWnd* , int , CToolTipCtrl& , CString& );

  virtual ~MyComboBox ();
  DECLARE_SERIAL(MyComboBox )

};

and

IMPLEMENT_SERIAL(MyComboBox , CMFCToolBarComboBoxButton,0)

MyComboBox ::MyComboBox (UINT uiID, int iImage, DWORD dwStyle , int iWidth  ) : CMFCToolBarComboBoxButton(uiID, iImage,dwStyle, iWidth )
{

}

MyComboBox ::MyComboBox ()
{

}

MyComboBox ::~MyComboBox ()
{
}

BOOL MyComboBox ::OnGetCustomToolTipText(CString& strToolTip) 
{ 
    strToolTip = "bonjour";
    return TRUE;
}

BOOL MyComboBox ::OnUpdateToolTip(CWnd* /*pWndParent*/, int /*iButtonIndex*/, CToolTipCtrl& /*wndToolTip*/, CString& str) 
{ 
  str = "allo";
  return TRUE; 
}

The 2 virtual methods are never called; well, they are called when opening the application and when closing the application; but never when the application is running normally when the user move/hover the mouse on top of the combobox in the toolbar.

I tried looking into the tooltip manager (CTooltipManager) and enable or not the tooltip manager by calling or not InitTooltipManager.

( I quickly tried this with VS2012 and I get the same "not-working" results).

Are there some steps I am missing to be able to do that ?

Thanks.

Max.

Max
  • 3,128
  • 1
  • 24
  • 24
  • I have also faced the same problem about how to dynamic change **CMFCToolBarButton** tooltips. And it's not solved yet now. If you don't use **CMFCToolBar** and **CMFCToolBarButton**, I think this a solution: [http://www.codeguru.com/cpp/controls/controls/tooltipcontrols/article.php/c2171/Change-tooltips-at-runtime.htm](http://www.codeguru.com/cpp/controls/controls/tooltipcontrols/article.php/c2171/Change-tooltips-at-runtime.htm) – alexzhang May 08 '13 at 16:43

3 Answers3

1

If I understand your problem, I believe you can derive from CMFCToolBar and override

virtual BOOL OnUserToolTip(CMFCToolBarButton* pButton, CString& strTTText) const 

to control the tooltip on demand.

darune
  • 10,480
  • 2
  • 24
  • 62
1
virtual BOOL GetToolbarButtonToolTipText(CMFCToolBarButton*/*pButton*/, CString&/*strTTText*/);
virtual void GetMessageString(UINT nID, CString& rMessage) const;

is the way to do it for CMFCToolBar and CMFCToolBarButton

Edit: You need to override GetMessageString in your MainFrame. For every id you give a description :

void CMainFrame::GetMessageString(UINT nID, CString& rMessage) const 
{
    switch (nID)
    {
        case 1:
        rMessage = "Hello World";
        break;
    }
} 

It displays description for button with id 1.

Fatima A.
  • 41
  • 13
  • you did not specify whereor how to override GetMessageString - it is not a method of CMFCToolBar. – darune Jul 03 '18 at 14:16
1

Anyone looking for answer here I did it this way. Made an extension class CMFCToolBarEx and wrote the function like

   BOOL CMFCToolBarEx::OnNeedTipText(UINT /*id*/, NMHDR* pNMH, LRESULT* /*pResult*/)
{
    TOOLTIPTEXT *pTTT = (TOOLTIPTEXT *)pNMH;
    CString strTip = _T("");

    CPoint point;
    ::GetCursorPos(&point);
    ScreenToClient(&point);
    INT_PTR nHit = ((CMFCToolBar*)this)->HitTest(point);

    if(nHit == -1)
        return FALSE;

    CMFCToolBarButton* pButton = GetButton((int)nHit);
    strTip = pButton->m_strText;
    _tcscpy(pTTT->lpszText , strTip.GetBuffer(0));

    return TRUE;
}

and message map ON_NOTIFY_EX_RANGE(TTN_NEEDTEXT, 0, 0xFFFF, &CMFCToolBarEx::OnNeedTipText)

This is when you add buttons yourself rather than resource through InsertButton function. It works fine for me except the description is not shown.

Fatima A.
  • 41
  • 13
  • Hello, Welcome to StackOverflow and thanks for taking part in helping people through your Answers. However, you don't need to provide any explanation in your comments. You can simply edit the answer and provide details there. also, have a look at https://stackoverflow.com/help/deleted-answers – Zeeshan Adil Sep 14 '18 at 10:43