Re: ToolTips in a View and TTN_NEEDTEXT
From: Rick Lee (Rick_at_Custom-Made-SoftwareNOSPAM.com)
Date: 11/19/04
- Next message: RP2001: "Interesting issue: Serializing CStrings"
- Previous message: Bob Moore: "Re: Calling two dialogs in InitInstance"
- In reply to: Bill Thompson: "Re: ToolTips in a View and TTN_NEEDTEXT"
- Next in thread: Bill Thompson: "Re: ToolTips in a View and TTN_NEEDTEXT"
- Reply: Bill Thompson: "Re: ToolTips in a View and TTN_NEEDTEXT"
- Messages sorted by: [ date ] [ thread ]
Date: Fri, 19 Nov 2004 14:35:10 -0800
Thanks, but I want Data Tips in a View, not in a dialog. In other words, as the
user moves the cursor over an object drawn in the View, he sees info about that
object.
Rick
Bill Thompson wrote:
>
> [code snipped]
>
> This class works for me. You derive your dialog based classes off of
> CToolTipDialog instead of CDialog, and 'voilez' your dialog has tooltips.
>
> NOTES:
> 1) Derive CToolTipDialog from CDialog (or whatever other base Dialog class
> you wish to use) instead of CResizeDialog
> 2) Derive dialogs that you want tool tips from this class.
> 3) A context menu has been included that allows you to set the
> tooltip from your program at run time. You have to either
> create a context menu resource with the resource ID
> IDR_TOOLTIP_MENU and a menu item to set the tooltip
> with ID IDR_SET_TOOLTIP, or delete the OnContextMenu
> code
> 4) This code uses a 'tooltip manager'. Since it's a database application,
> I store all toolips in a database. You may have another way to
> store your tooltips. Here's a (slightly revised) tooltip manager class:
> 5) You might want to associate resource ID's with the Dialog/Control ID's
> instead of strings.
>
> #ifndef TOOLTIPMANAGER_H
> #define TOOLTIPMANAGER_H
>
> class CToolTipManager
> {
> public:
> CToolTipManager();
> ~CToolTipManager();
> void Fini();
> // gets the tool tip associated with a given dialog/control
> void GetToolTipText(int DialogID, int ControlID, CString &ToolTip);
> // associates a tool tip with a given dialog/control
> bool SetToolTipText(int DialogID, int ControlID, CString &ToolTip);
> // invokes a dialog that let's the user add a tooltip
> void InvokeDialog(int DialogID, int ControlID);
>
> private:
> // you will want some member, such as a CMap type class
> // to associate tooltip text with dialog/controls here
> };
>
> ////////////////////////////////////////////////////////////////
> //***** Following is the tooltip dialog class:
> ////////////////////////////////////////////////////////////////
> #if
> !defined(AFX_TOOLTIPDIALOG_H__4FCE09A3_FBF1_4FB1_BAE6_1B1549FC88EE__INCLUDED
> _)
> #define AFX_TOOLTIPDIALOG_H__4FCE09A3_FBF1_4FB1_BAE6_1B1549FC88EE__INCLUDED_
>
> #if _MSC_VER > 1000
> #pragma once
> #endif // _MSC_VER > 1000
> // ToolTipDialog.h : header file
> //
>
> ////////////////////////////////////////////////////////////////////////////
> /
> // CToolTipDialog dialog
> // NOTE: replace CResizeDialog with CDialog,
> // or whatever base dialog class you are using.
>
> class CToolTipDialog : public CResizeDialog
> {
> DECLARE_DYNAMIC(CToolTipDialog)
> // Construction
> public:
> CToolTipDialog(UINT nIDD, LPCTSTR DialogTitle, bool UseScrollbars =
> false, CWnd* pParent = NULL); // standard constructor
>
> // Dialog Data
> //{{AFX_DATA(CToolTipDialog)
> // NOTE: the ClassWizard will add data members here
> //}}AFX_DATA
>
> // Overrides
> // ClassWizard generated virtual function overrides
> //{{AFX_VIRTUAL(CToolTipDialog)
> public:
> protected:
> virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
> //}}AFX_VIRTUAL
>
> // Implementation
> protected:
> LPCTSTR GetToolTipText(int ControlID);
> void GetToolTipControlFromPoint(CPoint point, int &ControlID, HWND
> &hWndChild) const;
> void OnSetToolTip();
>
> UINT m_nIDD;
> // stores the point from which the context menu was invoked
> CPoint m_PopupPoint;
>
> // Generated message map functions
> //{{AFX_MSG(CToolTipDialog)
> virtual BOOL OnInitDialog();
> afx_msg void OnContextMenu(CWnd* pWnd, CPoint point);
> //}}AFX_MSG
> BOOL OnToolTipNotify(UINT id, NMHDR *pNMH, LRESULT *pResult);
> virtual int OnToolHitTest( CPoint point, TOOLINFO* pTI ) const;
> DECLARE_MESSAGE_MAP()
> };
>
> //{{AFX_INSERT_LOCATION}}
> // Microsoft Visual C++ will insert additional declarations immediately
> before the previous line.
>
> #endif //
> !defined(AFX_TOOLTIPDIALOG_H__4FCE09A3_FBF1_4FB1_BAE6_1B1549FC88EE__INCLUDED
> _)
>
> ////////////////////////////////////////////////////////////////////
> ////////////////////////////////////////////////////////////////////
>
> // ToolTipDialog.cpp : implementation file
> //
>
> #include "stdafx.h"
> #include "NewTrader.h"
> #include "ToolTipDialog.h"
> #include "ToolTipManager.h"
> #include "Afx_OldToolInfo.h" // for OnToolHitTest
>
> extern CToolTipManager TheToolTipManager;
>
> #ifdef _DEBUG
> #define new DEBUG_NEW
> #undef THIS_FILE
> static char THIS_FILE[] = __FILE__;
> #endif
>
> // NOTE: again, you might want to replace all instances of CResizeDialog
> // with CDialog
> IMPLEMENT_DYNAMIC(CToolTipDialog, CResizeDialog)
>
> ////////////////////////////////////////////////////////////////////////////
> /
> // CToolTipDialog dialog
>
> CToolTipDialog::CToolTipDialog(UINT nIDD, LPCTSTR DialogTitle, bool
> UseScrollbars, CWnd* pParent)
> : CResizeDialog(nIDD, DialogTitle, UseScrollbars, pParent)
> {
> //{{AFX_DATA_INIT(CToolTipDialog)
> // NOTE: the ClassWizard will add member initialization here
> //}}AFX_DATA_INIT
> m_nIDD = nIDD;
> }
>
> void CToolTipDialog::DoDataExchange(CDataExchange* pDX)
> {
> CResizeDialog::DoDataExchange(pDX);
> //{{AFX_DATA_MAP(CToolTipDialog)
> // NOTE: the ClassWizard will add DDX and DDV calls here
> //}}AFX_DATA_MAP
> }
>
> BEGIN_MESSAGE_MAP(CToolTipDialog, CResizeDialog)
> //{{AFX_MSG_MAP(CToolTipDialog)
> ON_WM_CONTEXTMENU()
> ON_COMMAND(IDR_SET_TOOLTIP, OnSetToolTip)
> //}}AFX_MSG_MAP
> ON_NOTIFY_EX_RANGE(TTN_NEEDTEXT, 0, 0xFFFF, OnToolTipNotify)
> END_MESSAGE_MAP()
>
> ////////////////////////////////////////////////////////////////////////////
> /////
> // get the tool tip associated with a given control id
> LPCTSTR CToolTipDialog::GetToolTipText(int ControlID)
> {
> LPCTSTR RetVal = "";
> CWnd* pWndChild = GetWindow(GW_CHILD);
> int counter = 0;
> while (pWndChild != NULL)
> {
> int TestControlID = pWndChild->GetDlgCtrlID();
> if (ControlID == TestControlID)
> {
> static TCHAR MyBuf[256];
> CString ToolTipText;
> TheToolTipManager.GetToolTipText(m_nIDD, ControlID,
> ToolTipText);
> _tcscpy(MyBuf, ToolTipText);
> RetVal = MyBuf;
> }
> pWndChild = pWndChild->GetWindow(GW_HWNDNEXT);
> }
> return RetVal;
> }
>
> ////////////////////////////////////////////////////////////////////////////
> //
> // override the default OnToolHitTest
> // the code was copied from the MFC Source code.
> // the reason?
> // so tool tips follow the cursor rather than the bottom of the control
> int CToolTipDialog::OnToolHitTest(CPoint point, TOOLINFO* pTI) const
> {
> int nHit = -1;
> if (pTI != NULL && pTI->cbSize >= sizeof(AFX_OLDTOOLINFO))
> {
> // find child window which hits the point
> // (don't use WindowFromPoint, because it ignores disabled
> windows)
> HWND hWndChild = ::ChildWindowFromPoint(m_hWnd, point);
> if (hWndChild != NULL)
> {
> // back to the original code
> // return positive hit if control ID isn't -1
> nHit = ::GetDlgCtrlID(hWndChild);
> if (nHit != 0)
> {
> // setup the TOOLINFO structure
> pTI->hwnd = m_hWnd;
> pTI->uId = (UINT)hWndChild;
> pTI->uFlags |= TTF_IDISHWND;
> pTI->lpszText = LPSTR_TEXTCALLBACK;
> }
> }
> }
> return nHit;
> }
>
> ////////////////////////////////////////////////////////////////////////////
> /////
> // handle tool tip notification messages
> BOOL CToolTipDialog::OnToolTipNotify(UINT id, NMHDR *pNMH, LRESULT *pResult)
> {
> BOOL RetVal = FALSE;
> if (pNMH)
> {
> TOOLTIPTEXT *pText = (TOOLTIPTEXT *) pNMH;
> int ControlID = ::GetDlgCtrlID((HWND) pNMH->idFrom);
> if (ControlID)
> {
> pText->lpszText = (LPTSTR) GetToolTipText(ControlID);
> pText->hinst = AfxGetInstanceHandle();
> RetVal = TRUE;
> }
> }
> return RetVal;
> }
>
> ////////////////////////////////////////////////////////////////////////////
> /////
> ////////////////////////////////////////////////////////////////////////////
> /////
> void CToolTipDialog::GetToolTipControlFromPoint(CPoint point, int
> &ControlID, HWND &hWndChild) const
> {
> ControlID = -1;
> // find child window which hits the point
> // (don't use WindowFromPoint, because it ignores disabled windows)
> hWndChild = ::ChildWindowFromPoint(m_hWnd, point);
> if (hWndChild != NULL)
> {
> ControlID = ::GetDlgCtrlID(hWndChild);
> }
> }
>
> ////////////////////////////////////////////////////////////////////////////
> /
> // CToolTipDialog message handlers
>
> ////////////////////////////////////////////////////////////////////////////
> /
> ////////////////////////////////////////////////////////////////////////////
> /
> BOOL CToolTipDialog::OnInitDialog()
> {
> EnableToolTips(TRUE);
>
> CResizeDialog::OnInitDialog();
> return TRUE;
> }
>
> ////////////////////////////////////////////////////////////////////////////
> /
> ////////////////////////////////////////////////////////////////////////////
> /
> void CToolTipDialog::OnContextMenu(CWnd* /*pWnd*/, CPoint point)
> {
> m_PopupPoint = point;
> ScreenToClient(&m_PopupPoint);
> // make sure window is active
> GetParentFrame()->ActivateFrame();
>
> CMenu menu;
> if (menu.LoadMenu(IDR_TOOLTIP_MENU))
> {
> CMenu* pPopup = menu.GetSubMenu(0);
> ASSERT(pPopup != NULL);
> // check for admin mode later
> bool ToolTipsEnabled = true;
> pPopup->EnableMenuItem(IDR_SET_TOOLTIP, ToolTipsEnabled ? MF_ENABLED
> : MF_GRAYED);
> pPopup->TrackPopupMenu(TPM_RIGHTBUTTON | TPM_LEFTALIGN,
> point.x, point.y, this); // route commands
> through this window
> }
> }
>
> ////////////////////////////////////////////////////////////////////////////
> /
> ////////////////////////////////////////////////////////////////////////////
> /
> void CToolTipDialog::OnSetToolTip()
> {
> int ControlID;
> HWND hWndChild;
> GetToolTipControlFromPoint(m_PopupPoint, ControlID, hWndChild);
> if (ControlID != -1)
> {
> TheToolTipManager.InvokeDialog(m_nIDD, ControlID);
> }
> }
- Next message: RP2001: "Interesting issue: Serializing CStrings"
- Previous message: Bob Moore: "Re: Calling two dialogs in InitInstance"
- In reply to: Bill Thompson: "Re: ToolTips in a View and TTN_NEEDTEXT"
- Next in thread: Bill Thompson: "Re: ToolTips in a View and TTN_NEEDTEXT"
- Reply: Bill Thompson: "Re: ToolTips in a View and TTN_NEEDTEXT"
- Messages sorted by: [ date ] [ thread ]