Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1913
  • Last Modified:

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





0
wilsonian
Asked:
wilsonian
  • 6
  • 5
1 Solution
 
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
 
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
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
DanRollinsCommented:
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
 
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

Featured Post

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

  • 6
  • 5
Tackle projects and never again get stuck behind a technical roadblock.
Join Now