WTL 一个很好用的ToolTip(迁移2011-03-13)

         阅读(677)  2017-01-26 14:01:17

找到了一个老外写的很好用的ToolTip, 但是有两个小问题,终于解决了,拿出来和大家分享下。

  • 问题1:有时候出现这样的情况,鼠标划上去后立马弹出提示,然后消失,最后又弹出一次;

    解决方法:m_TT.SetDelayTime(TTDT_RESHOW, 1000);//鼠标划上过1秒后弹出提示;

  • 问题2:提示框弹出后默认只显示5秒钟就消失了, 这样时间太短了,提示的内容还没看完就消失了。

    解决方法:m_TT.SetDelayTime(TTDT_AUTOPOP, 10000);//弹出提示后停留10秒钟

源码:

#ifndef __TTDLG_H__
#define __TTDLG_H__
#pragma once
#ifndef __ATLCTRLS_H__
	#error ToolTipDlg.h requires atlctrls.h to be included first
#endif
#ifndef TTS_BALLOON
#define TTS_BALLOON 0
#endif
namespace WTL
{
template < class T ,class TT = CToolTipCtrl >
class CToolTipDlg
{
// Data declarations and members
public:
	TT& GetTT(){return m_TT;}
protected:
	TT m_TT;
	UINT m_uTTStyle;
	UINT m_uToolFlags;
// Construction
	CToolTipDlg( UINT uTTSTyle= TTS_NOPREFIX | TTS_BALLOON | TTS_ALWAYSTIP,
					UINT uToolFlags = TTF_IDISHWND | TTF_SUBCLASS) 
					: m_TT( NULL ), m_uTTStyle( uTTSTyle ), 
					m_uToolFlags( uToolFlags | TTF_SUBCLASS )
		{}
	void TTInit()
		{
		T* pT= (T*)this;
		ATLASSERT( ::IsWindow( *pT ));
		m_TT.Create( *pT, NULL, NULL, m_uTTStyle );
		CToolInfo ToolInfo( pT->m_uToolFlags, *pT , 0, 0, MAKEINTRESOURCE(pT->IDD) );
		m_TT.AddTool( &ToolInfo );
		m_TT.SetDelayTime(TTDT_RESHOW, 1000);//鼠标划上后1秒弹出提示
		m_TT.SetDelayTime(TTDT_AUTOPOP, 10000);//弹出提示后停留10秒钟
		::EnumChildWindows( *pT, SetTool, (LPARAM)pT );
		TTSize( 0 );
		TTActivate( TRUE );
		}
// Operations
public:
	void TTActivate(BOOL bActivate)
		{ m_TT.Activate( bActivate ); }
	void TTSize( int nPixel )
		{ m_TT.SetMaxTipWidth( nPixel );}
	void TTSetTxt( HWND hTool, _U_STRINGorID text )
		{ m_TT.UpdateTipText( text, hTool);}
	void TTSetTxt( UINT idTool, _U_STRINGorID text )
		{ TTSetTxt( GetHWND( idTool ) , text);}
	BOOL TTAdd( HWND hTool )
		{ return SetTool( hTool, (LPARAM)(T*)this );}
	BOOL TTAdd( UINT idTool )
		{ return TTAdd( GetHWND( idTool ));}
	void TTRemove( HWND hTool )
		{ m_TT.DelTool( hTool );}
	void TTRemove( UINT idTool )
		{ TTRemove( GetHWND( idTool ));}
// Message map and handlers
	BEGIN_MSG_MAP(CToolTipDlg)
		MESSAGE_RANGE_HANDLER(WM_MOUSEFIRST,WM_MOUSELAST, OnMouse)
		MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
	END_MSG_MAP()
		
	LRESULT OnInitDialog(UINT , WPARAM , LPARAM, BOOL& bHandled)
	{
		TTInit();
		bHandled = FALSE;
		return TRUE;
	}
	LRESULT OnMouse(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
	{
		T* pT = (T*)this;
		bHandled = FALSE;
		if(m_TT.IsWindow())
			m_TT.RelayEvent((LPMSG)pT->GetCurrentMessage());
		return 0;
	}
// Implementation
private:
	HWND GetHWND( UINT idTool )
		{ return ::GetDlgItem( *(T*)this, idTool );}
	static BOOL CALLBACK SetTool( HWND hTool, LPARAM pDlg)
		{
		T* pT = (T*)pDlg;
		int idTool = ::GetWindowLong(hTool, GWL_ID);
		if ( idTool != IDC_STATIC )
			{
			CToolInfo ToolInfo( pT->m_uToolFlags, hTool, 0, 0, (LPTSTR)idTool );
			pT->m_TT.AddTool( &ToolInfo );
			}
		return TRUE;
		}
};
} // namespace WTL
#endif // __TTDLG_H__

用法:

  1. 将上面的代码写入一个头文件中, 如:ToolTipDlg.h
  2. 在需要用的对话框中包含这个头文件, 并使其继承于CToolTipDlg类, 如:

    #include "ToolTipDlg.h"
    class CAboutDlg : public CDialogImpl<CAboutDlg>,
    	public CToolTipDialog<CAboutDlg>//here
    {
    public:
    	enum { IDD = IDD_ABOUTBOX };
    	BEGIN_MSG_MAP(CAboutDlg)
    		CHAIN_MSG_MAP(CToolTipDialog<CAboutDlg>)//here 一定要放在开始
    		MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
    		COMMAND_ID_HANDLER(IDOK, OnCloseCmd)
    		COMMAND_ID_HANDLER(IDCANCEL, OnCloseCmd)
    	END_MSG_MAP()
    ...
    };
    
  3. 如果要显示当鼠标滑动到某个静态文本控件上时弹出提示。首先,将IDC_STATIC改为其他的(如:IDC_TOOL_TIP);然后,将属性中的Notify设置为TRUE;最后,打开String Table, ID为先前修改后的ID(如:IDC_TOOL_TIP), 标题为提示框中要显示的内容, 换行的话可以加/n。

简单的用法就是上面这样子的, 至于其他的用法可以看源码给出的函数。

文章评论

Keep it simple,stupid
文章数
283
总访问量
260049
今日访问
379
最近评论

ningto : 请到next.ningto.com里发表评论。
tujiaw : 抱歉csdn code服务关闭了,这个代码我也找不到了
于淞 : 你好,这个文章的源码能分享一下吗,songsong9181@163.com,谢谢了 上面的写错了
于淞 : 你好,这个文章的源码能分享一下吗,838106303@163.com,谢谢了 上面的链接不能用了
tujiaw : 多谢多谢
essaypinglun college-paper.org : 很好的博客,赞赞
Folly : 这个实现有点奇怪,Qt为什么没有统一的比对方法。
过多s : alert("hello, world!")
tujiaw : 还不错哦
回到顶部