Tool tip for subclassed CButton

Hi there,

I have subclassed CButton and want to have a tooltip on it.

I have previously got tooltips working for several controls in a CWnd, controlled by the CWnd, but I want this CButton to have all the code for its own tooltips, not its parent window.  I have tried transplanting the code that worked for the CWnd, but using this instead of the controls in AddTool, ie:

in MyButton::OnCreate:
      EnableToolTips(TRUE);
      m_tooltip.Create(this, TTS_NOPREFIX| TTS_ALWAYSTIP);
      m_tooltip.Activate(TRUE);
      m_tooltip.AddTool(this, _T("text"));

I've overloaded PreTranslateMessage to have m_tooltip.RelayEvent(pMsg);

This isn't working.  I don't know whether I'm going about this right but making a mistake somewhere, or whether I need a completely different approach. What should I be doing?

Thank you





wilsonianAsked:
Who is Participating?
 
DanRollinsConnect With a Mentor Commented:
Heres' the header:
#pragma once

/////////////////////////////////////////////////////////////////////////////
// CMyButton window

class CMyButton : public CButton
{
// Construction
public:
      CMyButton();
      virtual ~CMyButton();

      BOOL PreTranslateMessage(MSG* pMsg);

      CString m_sTipText;
      void SetTipText( LPCSTR sz ) { m_sTipText= sz; };

      CToolTipCtrl m_tooltip;

      // ClassWizard generated virtual function overrides
      //{{AFX_VIRTUAL(CMyButton)
      protected:
      virtual void PreSubclassWindow();
      //}}AFX_VIRTUAL


      // Generated message map functions
protected:
      //{{AFX_MSG(CMyButton)
      //}}AFX_MSG

      DECLARE_MESSAGE_MAP()
};
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
here's the CPP file:

// MyButton.cpp : implementation file
//
#include "stdafx.h"
#include "MyButton.h"

CMyButton::CMyButton() { }
CMyButton::~CMyButton() { }

BEGIN_MESSAGE_MAP(CMyButton, CButton)
      //{{AFX_MSG_MAP(CMyButton)
      //}}AFX_MSG_MAP
END_MESSAGE_MAP()

void CMyButton::PreSubclassWindow()
{
      CButton::PreSubclassWindow();
      if (m_sTipText > "" ) {
            EnableToolTips( TRUE );
            m_tooltip.Create(this, TTS_NOPREFIX| TTS_ALWAYSTIP );
            m_tooltip.AddTool(this, (LPCSTR)m_sTipText );
            m_tooltip.Activate(TRUE);
      }
}
//-------------------------------------------------------------
BOOL CMyButton::PreTranslateMessage(MSG* pMsg)
{
      switch(pMsg->message) {
            case WM_LBUTTONDOWN:
            case WM_LBUTTONUP:
            case WM_MOUSEMOVE:
                  if ( m_tooltip.m_hWnd ) {
                        m_tooltip.RelayEvent(pMsg);
                  }
            break;
      }
      return CButton::PreTranslateMessage(pMsg);
}
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
here's an example impementation (partial):

void CD18Dlg::DoDataExchange(CDataExchange* pDX)
{
      CDialog::DoDataExchange(pDX);
      //{{AFX_DATA_MAP(CD18Dlg)
      DDX_Control(pDX, IDPB_MyButton, m_ctlMyButton);
      //}}AFX_DATA_MAP
}

.... etc...

BOOL CD18Dlg::OnInitDialog()
{
      m_ctlMyButton.SetTipText("this is the tip text");

      CDialog::OnInitDialog();

.... etc...

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
You could use other method to set the tip text... my implementation is not dynamic, but this should get you going.

It seems to boil down to
   provide a CToolTip member for the CButton-derived object
   Create the tooltip in PreSubclassWindow
   Handle PreTranslateMessage and use .RelayEvent on certain msgs

-- Dan
0
 
DanRollinsCommented:
One normally handles the tooltips in the parent.  There is some good code here:

     http:/MFC/Q_10037333.html

And it is covered nicely in MDSN.

-- Dan
0
 
DanRollinsCommented:
It is also possible to do it in the button itself, but the technique description differs depending upon how you are creating the button.  If you place a breakpoint in your OnCreate fn, does it get executed?

-- Dan
0
Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

 
wilsonianAuthor Commented:
Heh, you'd think I'd check something like that.  No, OnCreate is not getting called. What function should the tooltip code live in, or do I have to write one that I call explicitly?

The buttons are member variables of a couple of different types of CWnd (CDialog and CPropertyPage at the moment)

I don't want to handle the tooltips in the parent because the buttons appear in different contexts and it would save doing it more than once, also the tool tips really are part of the functionality of the button itself (they're not serving the normal purpose of tool tips).
0
 
wilsonianAuthor Commented:
I now get an assert failure in the following line:

      m_tooltip.Create(this, TTS_NOPREFIX| TTS_ALWAYSTIP);

in AfxHookWindowCreate.  It's on line 627 and says:

ASSERT(pThreadState->m_hHookOldCbtFilter != NULL);

Any idea what's going on here?
0
 
DanRollinsCommented:
Myabe it's something you are doing in your OnCreate fn.  I did not use one.

-- Dan
0
 
wilsonianAuthor Commented:
I deleted OnCreate when I put the PreSubclassWindow function in, so that can't be it.
0
 
DanRollinsCommented:
I'm pretty certain that that ASSERT indicates that some window is being created while another window is still in the process of being created.  Does that narrow it down?  

I assure you that the code I posted does work in a minimal AppWizard-generated Dialog-based program.

-- Dan
0
 
DanRollinsCommented:
Be sure to call
   m_tooltip.Create( this, ...
when the 'this' pointer identifies a CWnd-derived object that has already been created (that is, its m_hWnd member is valid).

-- Dan
0
 
wilsonianAuthor Commented:
Sorry, my email was playing up and I didn't get your message.

I'll check it out on Friday when I'm next at work.
0
 
wilsonianAuthor Commented:
It's still not working, but I'm sure it's some weird unrelated thing I'm doing.  I'm awarding you the points.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.