06-17-2009 11:18 AM
I have found a general solution for display tooltips with CNiNumEdit. The problem, on my opinion, is relative the Edit control that the class use for I/O.
This control is overlapping the control window and hide the control window to the tooltips manager.
I wrote a workaround to get the CWnd* of the Edit control and the tooltipo works!
NumeditEx.h
--------------------------------------------------------------------------------------------
#pragma once #include "ninumedit.h" ////////////////////////////////////////////////////////////////////////////////////////// // Summary: Enhanced CNiNumEdit. The class provides extra functionality to manage // tooltips ////////////////////////////////////////////////////////////////////////////////////////// class CNiNumEditEx : public NI::CNiNumEdit { DECLARE_DYNAMIC(CNiNumEditEx) TCHAR* m_ptchar; // tooltip text for windows tooltip notification CNiString m_strToolTip; // tooltip from resources public: CNiNumEditEx(); virtual ~CNiNumEditEx(); protected: virtual void DoDataExchange(CDataExchange* pDX); public: // // Summary: Returns the window pointer of the overlapping CEdit control // Returns: The window pointer of the overlapping CEdit control or NULL if fails // CWnd* GetEditWindow(); public: afx_msg BOOL OnToolTipNotify(UINT nID, NMHDR* pNMHDR, LRESULT* pResult); DECLARE_MESSAGE_MAP() DECLARE_EVENTSINK_MAP() };
NumEditEx.cpp
---------------------------------------------------------------------------------------------------------
#include "stdafx.h" #include "NumEditEx.h" IMPLEMENT_DYNAMIC( CNiNumEditEx, NI::CNiNumEdit ) BEGIN_MESSAGE_MAP(CNiNumEditEx, NI::CNiNumEdit) ON_NOTIFY_EX( TTN_NEEDTEXT, 0, OnToolTipNotify ) END_MESSAGE_MAP() BEGIN_EVENTSINK_MAP(CNiNumEditEx, NI::CNiNumEdit) END_EVENTSINK_MAP() // *************************************************************************************** CNiNumEditEx::CNiNumEditEx() { m_ptchar = NULL; } // *************************************************************************************** CNiNumEditEx::~CNiNumEditEx() { if( m_ptchar != NULL ) m_strToolTip.ReleaseBuffer(); } // *************************************************************************************** void CNiNumEditEx::DoDataExchange(CDataExchange* pDX) { NI::CNiNumEdit::DoDataExchange(pDX); } // *************************************************************************************** CWnd* CNiNumEditEx::GetEditWindow() { CWnd* wnd = NULL; HWND hWndThisChild = NULL; HWND hWndEdit = NULL; _TCHAR szClassName[1024]; // Go through the child windows hWndThisChild = ::GetWindow(GetSafeHwnd(), GW_CHILD); while (hWndThisChild) { // If we got the class name... if (::GetClassName(hWndThisChild, szClassName, 1024)) { // And if class name is same as the one we're looking for... if (lstrcmp(szClassName, "Edit") == 0) { // Bingo hWndEdit = hWndThisChild; break; } } // Get next child window hWndThisChild = ::GetNextWindow(hWndThisChild, GW_HWNDNEXT); } if( hWndEdit ) { wnd = CWnd::FromHandle(hWndEdit); } return wnd; } // *************************************************************************************** BOOL CNiNumEditEx::OnToolTipNotify(UINT id, NMHDR* pNMHDR, LRESULT* pResult) { TOOLTIPTEXT *pTTT = (TOOLTIPTEXT *)pNMHDR; UINT nID =pNMHDR->idFrom; if (pTTT->uFlags & TTF_IDISHWND) { // idFrom is actually the HWND of the tool nID = ::GetDlgCtrlID((HWND)nID); if(nID) { if( m_ptchar == NULL ) { m_strToolTip.LoadString(nID); m_ptchar = m_strToolTip.GetBuffer(); } pTTT->lpszText = m_ptchar; pTTT->hinst = AfxGetResourceHandle(); return(TRUE); } } return(FALSE); }
Usage:
// // Gestione dei tooltip // m_tooltip.Create(this); m_tooltip.SetDebugMode(FALSE); m_tooltip.SetEffectBk(CPPDrawManager::EFFECT_VGRADIENT); m_tooltip.SetIgnoreEnabledStatus(TRUE); SUPER_TOOLTIP_INFO sti; sti.bSuperTooltip = TRUE; sti.nVirtualKeyCode = 0; sti.nKeyCodeId = 0; sti.nIDTool = 0; sti.nSizeX = 400; sti.bLineAfterHeader = FALSE; sti.strFooter = ""; sti.nFooterImage = 0; sti.bLineBeforeFooter = TRUE; sti.rgbBegin = RGB(255, 255, 255); sti.rgbMid = RGB(242, 246, 251); sti.rgbEnd = RGB(202, 218, 239); sti.rgbText = RGB(76, 76, 76); sti.nSizeX = 212; sti.strHeader = "Indicatore Posizione Asse"; sti.strBody = "<indent>Indica la posizione attuale del'asse</indent>.<br>" "<indent>Quando lo sfondo del controllo è giallo l'asse è in movimento," "a posizione raggiunta lo sfondo è bianco.</indent><br>"; sti.pWnd = ((CNiNumEditEx*)GetDlgItem(IDC_IND_AXE1))->GetEditWindow(); m_tooltip.AddTool(&sti);
Let me know if useful.
Have a nice day
Roberto Guerzoni
Tecnologic s.r.l. campogalliano (MO) Italy