怎样给VC中的List控件添加ToolTip

 我来答
福喜900
2015-01-13 · TA获得超过6.1万个赞
知道大有可为答主
回答量:1.1万
采纳率:0%
帮助的人:1亿
展开全部

 VC6的List控件默认是不能为subitem提供tooltip的,只有通过重写CListCtrl类来实现。在网上找了一个写好的CToolTipListCtrl类可以显示该功能,只需调用即可。具体步骤如下:

  1.将ToolTipListCtrl.h和ToolTipListCtrl.cpp加入工程。

  2.为List控件添加相应的变量CListCtrl m_lstObject。

  3.用CToolTipListCtrl替换上面的CListCtrl,当然还要加入相应的头文件“#include "ToolTipListCtrl.h"”。

  4.设置列表的扩展样式,使之包含LVS_EX_INFOTIP样式。

    m_lstObject.SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_INFOTIP);

  5.步骤4也可以改为

    m_lstObject.SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);

    m_lstObject.EnableToolTips(TRUE);

  6.编译运行程序。效果见下图:

是不是很简单呢,你也赶快试试吧。

  下面是ToolTipListCtrl.h和ToolTipListCtrl.cpp源码:

#if !defined(AFX_TOOLTIPLISTCTRL_H__EA17BA6D_ADD2_49E3_AB67_45B65316D19F__INCLUDED_)
#define AFX_TOOLTIPLISTCTRL_H__EA17BA6D_ADD2_49E3_AB67_45B65316D19F__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// ToolTipListCtrl.h : header file
//

/////////////////////////////////////////////////////////////////////////////
// CToolTipListCtrl window

#include <afxtempl.h>

/////////////////////////////////////////////////////////////////////////////
// CToolTipListCtrl, v.1.0
//
// A CListCtrl derived class that
// can display per SubItem tooltips by itself
//
// Author: Jo鉶 Filipe de Castro Ferreira (jfilipe@isr.uc.pt)
// Based on Nate Maynard's (nate.maynard@neomation.com) CToolTipTreeCtrl
//
// Last Modified: 7/11/2001
//
// License: Quoting Nate Maynard,
//  "use it however you want. If it helps you out, drop me a line and let me know. :-)"
//
// Disclaimer: This code comes with no warranty of any kind whatsoever. Use at your own risk.
//
/////////////////////////////////////////////////////////////////////////////

//The initial state of m_wHitMask
#define INITIAL_HITMASK LVHT_ONITEMLABEL

class CToolTipListCtrl : public CListCtrl
{
// Construction
public:
   CToolTipListCtrl();

// Attributes
public:

protected:
   // Map's SubItems to related tooltip text
   CMapStringToString m_ToolTipMap;
   // A bit mask of LVHT_* flags the control will show tooltips for
   WORD m_wHitMask;

// Operations
public:

// Overrides
   // ClassWizard generated virtual function overrides
   //{{AFX_VIRTUAL(CToolTipListCtrl)
   //}}AFX_VIRTUAL

// Implementation
public:


   //** CWnd Overrides **
   //Provide our own logic for HitTests, specifically, make ToolHitTests respond per SubItem
   virtual int OnToolHitTest(CPoint point, TOOLINFO * pTI) const;

   
   //** CTreeCtrl Overrides **
   //Overriding the Delete functions makes sure m_ToolTipMap doesn't have excess mappings
   virtual BOOL DeleteAllItems( );
   virtual BOOL DeleteItem( int nItem );
   virtual BOOL SetItemText( int nItem, int nSubItem, LPTSTR lpszText );


   //** Additional Functions **

   //Set the TVHT_* flags that will trigger the display of a tooltip
   WORD SetToolTipHitMask(WORD wHitMask);
   //Clear all tooltips
   virtual void DeleteAllToolTips();
   //Set the tooltip text for a specific SubItem
   virtual BOOL SetItemToolTipText( int nItem, int nSubItem, LPCTSTR lpszToolTipText );
   //Retrieves the tooltip text for a specific SubItem
   virtual CString GetItemToolTipText( int nItem, int nSubItem );

   
   virtual ~CToolTipListCtrl();

   // Generated message map functions
protected:
   //{{AFX_MSG(CToolTipListCtrl)
       // NOTE - the ClassWizard will add and remove member functions here.
   //}}AFX_MSG

   //Respondes to the TTN_NEEDTEXT* messages, provides the text of a tooltip
   virtual afx_msg BOOL OnToolTipText( UINT id, NMHDR * pNMHDR, LRESULT * pResult );

   DECLARE_MESSAGE_MAP()
};

/////////////////////////////////////////////////////////////////////////////

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_TOOLTIPLISTCTRL_H__EA17BA6D_ADD2_49E3_AB67_45B65316D19F__INCLUDED_)

// ToolTipListCtrl.cpp : implementation file
//

#include "stdafx.h"
#include "ToolTipListCtrl.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CToolTipListCtrl

CToolTipListCtrl::CToolTipListCtrl()
{
   m_wHitMask = INITIAL_HITMASK;
}

CToolTipListCtrl::~CToolTipListCtrl()
{
   // Cleanup when destroyed

   DeleteAllToolTips();
}

BEGIN_MESSAGE_MAP(CToolTipListCtrl, CListCtrl)
   //{{AFX_MSG_MAP(CToolTipListCtrl)
   // NOTE - the ClassWizard will add and remove mapping macros here.
   //}}AFX_MSG_MAP

   //Trap all TTN_NEEDTEXT* Messages
   //TTN_NEEDTEXT* messages are sent when a ToolTipCtrl wants a control
   //to provide it with text to display as the tooltip.
   //Specifically, when the TOOLINFO structure passed back to the ToolTipCtrl
   //after ::OnToolHitTest has it's lpszText memeber set to LPSTR_TEXTCALLBACK.

   ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTW, 0, 0xFFFF, OnToolTipText)
   ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTA, 0, 0xFFFF, OnToolTipText)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CToolTipListCtrl message handlers

int CToolTipListCtrl::OnToolHitTest(CPoint point, TOOLINFO * pTI) const
{
   // See if the point falls onto a list item
   //UINT nFlags = 0;
   
   LVHITTESTINFO lvhitTestInfo;
   
   lvhitTestInfo.pt = point;
   
   int nItem = ListView_SubItemHitTest(
       this->m_hWnd,
       &lvhitTestInfo);
   int nSubItem = lvhitTestInfo.iSubItem;
   
   UINT nFlags = lvhitTestInfo.flags;
   
   // nFlags is 0 if the SubItemHitTest fails
   // Therefore, 0 & <anything> will equal false
   if (nFlags & m_wHitMask)
   {
       // If it did fall on a list item,
       // and it was also hit one of the
       // item specific sub-areas we wish to show tool tips for
       
       // Get the client area occupied by this control
       RECT rcClient;
       GetClientRect( &rcClient );
       
       // Fill in the TOOLINFO structure
       pTI->hwnd = m_hWnd;
       pTI->uId = (UINT) (nItem * 100 + nSubItem);
       pTI->lpszText = LPSTR_TEXTCALLBACK;
       pTI->rect = rcClient;
       
       return pTI->uId; // By returning a unique value per listItem,
       // we ensure that when the mouse moves over another list item,
       // the tooltip will change
   }
   else
   {
       // Otherwise, we aren't interested, so let the message propagate
       return -1;
   }
}

BOOL CToolTipListCtrl::OnToolTipText( UINT id, NMHDR * pNMHDR, LRESULT * pResult )
{
   // Handle both ANSI and UNICODE versions of the message
   TOOLTIPTEXTA* pTTTA = (TOOLTIPTEXTA*)pNMHDR;
   TOOLTIPTEXTW* pTTTW = (TOOLTIPTEXTW*)pNMHDR;
   
   // Ignore messages from the built in tooltip, we are processing them internally
   if( (pNMHDR->idFrom == (UINT)m_hWnd) &&
       ( ((pNMHDR->code == TTN_NEEDTEXTA) && (pTTTA->uFlags & TTF_IDISHWND)) ||
       ((pNMHDR->code == TTN_NEEDTEXTW) && (pTTTW->uFlags & TTF_IDISHWND)) ) )
   {
       return FALSE;
   }
   
   *pResult = 0;
   
   CString strTipText;
   
   // Get the mouse position
   const MSG* pMessage;
   pMessage = GetCurrentMessage();
   ASSERT ( pMessage );
   CPoint pt;
   pt = pMessage->pt; // Get the point from the message
   ScreenToClient( &pt ); // Convert the point's coords to be relative to this control
   
   // See if the point falls onto a list item
   
   LVHITTESTINFO lvhitTestInfo;
   
   lvhitTestInfo.pt = pt;
   
   int nItem = SubItemHitTest(&lvhitTestInfo);
   int nSubItem = lvhitTestInfo.iSubItem;
   
   UINT nFlags = lvhitTestInfo.flags;
   
   // nFlags is 0 if the SubItemHitTest fails
   // Therefore, 0 & <anything> will equal false
   if( nFlags & m_wHitMask )
   {
       // If it did fall on a list item,
       // and it was also hit one of the
       // item specific sub-areas we wish to show tool tips for
       
       // Lookup the list item's text in the ToolTip Map
       
       CString strKey;
       
       strKey.Format(_T("%d"),  nItem * 100 + nSubItem);
       
       if( m_ToolTipMap.Lookup(strKey, strTipText ) )
       {
           // If there was a CString associated with the list item,
           // copy it's text (up to 80 characters worth, limitation of the TOOLTIPTEXT structure)
           // into the TOOLTIPTEXT structure's szText member
           
           // Deal with UNICODE
#ifndef _UNICODE
           if (pNMHDR->code == TTN_NEEDTEXTA)
               lstrcpyn(pTTTA->szText, strTipText, 80);
           else
               _mbstowcsz(pTTTW->szText, strTipText, 80);
#else
           if (pNMHDR->code == TTN_NEEDTEXTA)
               _wcstombsz(pTTTA->szText, strTipText, 80);
           else
               lstrcpyn(pTTTW->szText, strTipText, 80);
#endif
         
       }
   }
   
   return FALSE; // We didn't handle the message,
   // let the framework continue propagating the message
}

// Sets the tooltip text for a specific item
BOOL CToolTipListCtrl::SetItemToolTipText( int nItem, int nSubItem, LPCTSTR lpszToolTipText )
{
   CString strKey;
   
   strKey.Format(_T("%d"),  nItem * 100 + nSubItem);
   
   m_ToolTipMap.SetAt( strKey, lpszToolTipText );
   
   return TRUE;
}

// Retrieve the tooltip text for a specific list item
CString CToolTipListCtrl::GetItemToolTipText( int nItem, int nSubItem )
{
   CString itemToolTipText;
   
   CString strKey;
   
   strKey.Format(_T("%d"),  nItem * 100 + nSubItem);
   
   
   if( !m_ToolTipMap.Lookup( strKey, itemToolTipText ) )
   {
       itemToolTipText = "";
   }
   
   return itemToolTipText;
}

WORD CToolTipListCtrl::SetToolTipHitMask( WORD wHitMask )
{
   WORD oldHitMask = m_wHitMask;
   
   m_wHitMask = wHitMask;
   
   return oldHitMask;
}

void CToolTipListCtrl::DeleteAllToolTips()
{
   m_ToolTipMap.RemoveAll();
}

BOOL CToolTipListCtrl::DeleteAllItems( )
{
   // Call the base class method
   BOOL retVal = CListCtrl::DeleteAllItems();
   
   if( retVal )
   {
       // If it succeeded, remove all tooltips
       DeleteAllToolTips();
   }
   
   return retVal;
}

BOOL CToolTipListCtrl::DeleteItem( int nItem )
{
   // Call the base class method
   BOOL retVal = CListCtrl::DeleteItem( nItem );
   
   if( retVal )
   {

推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式