tooltip2 与 ctooltipctrl 小结

news/2024/11/7 7:46:06/

 MFC中有一个CToolTipCtrl类,想必大家都知道,近来我在一个项目中需要在ActiveX Control上为特定的控件或区域添加提示.开始使用CToolTipCtrl,但发现它根本就不工作.无奈,只好自己写了一个类来实现它.
该类为CTip(包含CTip.c和CTip.h)
你只需在你的工程中加入它,就可以使用.
使用步骤:
        1.在初始化时Create(CWnd* pParentWnd).
        2.在MoseMove(CPoint point)中调用SetText(const CString& rsText)来设置要显示的文本.
        3.在MoseMove(CPoint point)中调用Show(CPoint point)显示该提示.
使用说明:
        1.Create中所作的是用CreateEX来创建一个窗口,这个窗口的大小为0,显示标题为空,风格为WS_POPUP&brvbarWS_CHILD&brvbarWS_CLIPSIBLINGS
        2.这里有一个技巧,你必须知道当你的鼠标位于哪个范围时,该提示应当出现.因此你可以有两种选择:之一,你直接指定该范围(设置一个CRect)或是添加一个成员变量来动态记录该范围;之二,你可以调用如下:  
          CRect rect;
          CWnd* pwnd = GetDlgItem(ID_xxx);
          pwnd->GetWindowRect(&rect);
          ScreenToClient(&rect);
          这样也可以得到当前的rect.然后你可以调用如下:
          if(rect.PtInRect(point))
          {
              m_tip.SetText(m_varname);
              m_tip.Show(point);
          }
          else 
          {        
              m_tip.Close();
          }
        3.show和close用来显示和隐藏提示,在show中主要是利用CDC来进行绘制提示.
几个主要函数的具体代码:
BOOL CToolTip2::Create(CWnd* pParentWnd)
{
ASSERT(this != NULL );
ASSERT(pParentWnd != NULL);

m_pParentWnd = pParentWnd;
//  Create font
CRect rectInitialSize(0,0,0,0);//Initial Window size. Will be dynamically 
return CreateEx(NULL, NULL, NULL,WS_POPUP ¦  WS_CHILD ¦ WS_CLIPSIBLINGS,
  rectInitialSize,pParentWnd, NULL, NULL);
}

BOOL CToolTip2::Show(const CPoint& rCurrentPoint)
{
ASSERT(this != NULL );
ASSERT(m_hWnd != NULL );
//  Is text empty or tool tip already displayed?
if ( m_szText.IsEmpty() ¦¦ m_bShowStatus)
  return FALSE;
m_ptCurrent = rCurrentPoint;
m_bShowStatus = TRUE;
//  show tool tip
DisplayToolTip(rCurrentPoint);
return TRUE;
}

void CToolTip2::DisplayToolTip(const CPoint& rCurrentPoint)
{
CDC* pDC = GetDC();
CBrush  *pOldBrush;
CFont *pOldFont;

pOldFont = pDC->SelectObject(&m_font);
CSize size = pDC->GetTextExtent(m_szText);
pDC->LPtoDP(&size);
//  form tooltip rectangle
CRect rectToolTip(rCurrentPoint.x, rCurrentPoint.y, 
rCurrentPoint.x+size.cx+7, rCurrentPoint.y+size.cy+2);
//  draw Tooltip Rect and Text
pDC->SetBkMode(TRANSPARENT);
CBrush brushToolTip(GetSysColor(COLOR_INFOBK));
pOldBrush = pDC->SelectObject(&brushToolTip);
//  Create and select thick black pen
CPen penBlack(PS_SOLID, 0, COLORREF(RGB(0, 0, 0)));
CPen* pOldPen = pDC->SelectObject(&penBlack);
//  draw rectangle filled with COLOR_INFOBK
pDC->Rectangle(0,0,rectToolTip.Width(),rectToolTip.Height());
//  draw tooltip text
    pDC->SetTextColor( GetSysColor(COLOR_INFOTEXT) );//Tool Tip color set in 
//  control panel settings
pDC->SetTextAlign(TA_LEFT);
pDC->TextOut(3,1, m_szText);
CRect rectWnd = rectToolTip;
m_pParentWnd->ClientToScreen(rectWnd); //  Convert from client to screen 
CPoint ptToolTipLeft = rectWnd.TopLeft();
//  now display tooltip
SetWindowPos(&wndTop,ptToolTipLeft.x+1, ptToolTipLeft.y+1, rectWnd.Width(), 
rectWnd.Height(),SWP_SHOWWINDOW&brvbarSWP_NOOWNERZORDER&brvbarSWP_NOACTIVATE);
// put back old objects
pDC->SelectObject(pOldBrush);
pDC->SelectObject(pOldPen);
pDC->SelectObject(pOldFont);
ReleaseDC(pDC);
}

 

 

 

Another

一个项目中要用到ToolTip提示功能,由于是在VIEW中使用,所以不大好用MFC中的CToolTipCtrl来实现,CToolTipCtrl针对CButton,和CStatic ,CEdit来说比较好用,但在VIEW中要根据鼠标的位置来显示不同的ToolTip,这时用CToolTipCtrl类就不大好实现。

        在CodeGuru上找到Dhandapani Ammasai写的一个CToolTip2类,这个类很方便地实现了这个功能。

      下面介绍用法。在鼠标移动响应函数OnMouseMove里面加上下面语句:

 //显示ToolTip

 if(point.x>0&&point.x<100 &&point.y>0&&point.y<100)//在选定出现文字区域
 {
  m_ToolTip.SetText("OK");
  m_ToolTip.Show(point);
 }
 else
 {
  m_ToolTip.Close();
 }

  下面是CTooltip的源文件

//File: CToolTip2.h
//Header file for class CToolTip2
//Copyright (C) 2000  Dhandapani Ammasai( dammasai@hotmail.com )
//Mail your comments, criticism, bugs to the above e-mail address.
#ifndef _TOOL_TIP_2_H_
#define _TOOL_TIP_2_H_
#include "stdafx.h"

class CToolTip2 : public CWnd
{
DECLARE_DYNAMIC( CToolTip2 );
private: //data members
 //Tooltip Text
 CString m_szText;
 //Parent Window
 CWnd* m_pParentWnd;
 //Show Status
 BOOL m_bShowStatus;
 //Current point where tooltip is displayed
 CPoint m_ptCurrent;
 //Font
 CFont m_font;
private: //Methods
 //Display Tooltip Window
 void DisplayToolTip(const CPoint& rCurrentPoint);
 //Copy constructor
 CToolTip2(const CToolTip2&);
 //Assignment operator
 CToolTip2& operator=(const CToolTip2&);
public: //Methods
 //Default Constructor
 CToolTip2();
 //Destructor
 ~CToolTip2();
 //Create tootip
 BOOL Create(CWnd* pParentWnd);
 //Set tooltip text
 void SetText(const CString&);
 //Show the tooltip
 BOOL Show(const CPoint&);
 //Close the tooltip
 void Close();
protected:
 // Generated message map functions
 //{{AFX_MSG(CToolTip2)
 afx_msg void OnPaint();
 //}}AFX_MSG
 DECLARE_MESSAGE_MAP()
};
#endif
 //

//File: ToolTip2.cpp
//Implementation file for class CToolTip2
//Copyright (C) 2000  Dhandapani Ammasai( dammasai@hotmail.com )
//Mail your comments, criticism, bugs to the above e-mail address.
#include "stdafx.h"
#include "tooltip2.h"

IMPLEMENT_DYNAMIC( CToolTip2, CWnd );

BEGIN_MESSAGE_MAP(CToolTip2, CWnd)
 //{{AFX_MSG_MAP(CToolTip2)
 ON_WM_PAINT()
 //}}AFX_MSG_MAP
END_MESSAGE_MAP()

//Default Constructor
CToolTip2::CToolTip2()
{
 m_szText = "";
 m_pParentWnd = NULL;
 m_bShowStatus = FALSE;
}

//Destructor
CToolTip2::~CToolTip2()
{
}

//Create Tool Tip
BOOL CToolTip2::Create(CWnd* pParentWnd)
{
 ASSERT(this != NULL );
 ASSERT(pParentWnd != NULL);

 m_pParentWnd = pParentWnd;
 //Create font
 m_font.CreateFont(15, 0, 0, 0, FW_REGULAR, 0, 0, 0, 0, 0, 0, 0, 0, "MS Sans Serif");
 CRect rectInitialSize(0,0,0,0);//Initial Window size. Will be dynamically changed later.
 return CreateEx(NULL, NULL, NULL,WS_POPUP |  WS_CHILD | WS_CLIPSIBLINGS,
  rectInitialSize,pParentWnd, NULL, NULL);
}

//Set tooltip text
void CToolTip2::SetText(const CString& rsText)
{
 ASSERT(this != NULL );
 m_szText = rsText;
 m_szText.TrimRight();
}

//Show tooltip
//rCurrentPoint specifies current mouse position and it is in client
//coordinates of parent window(Not in screen coordinates).
BOOL CToolTip2::Show(const CPoint& rCurrentPoint)
{
 ASSERT(this != NULL );
 ASSERT(m_hWnd != NULL );

 //Is text empty or tool tip already displayed?
 if ( m_szText.IsEmpty() || m_bShowStatus)
  return FALSE;

 m_ptCurrent = rCurrentPoint;
 m_bShowStatus = TRUE;
 //Show tool tip
 DisplayToolTip(rCurrentPoint);
 return TRUE;
}

//Close the tooltip
void CToolTip2::Close()
{
 ASSERT(this != NULL );
 ASSERT(m_hWnd != NULL );

 ShowWindow(SW_HIDE); //Hide tooltip
 m_bShowStatus = FALSE;
}

void CToolTip2::OnPaint()
{
 CPaintDC dc(this);

 DisplayToolTip(m_ptCurrent);
}

//Display tooltip
void CToolTip2::DisplayToolTip(const CPoint& rCurrentPoint)
{
 CDC* pDC = GetDC();

 CBrush  *pOldBrush;

 CFont *pOldFont;
 pOldFont = pDC->SelectObject(&m_font);
 CSize size = pDC->GetTextExtent(m_szText);
 pDC->LPtoDP(&size);
 //Form tooltip rectangle
 CRect rectToolTip(rCurrentPoint.x, rCurrentPoint.y,rCurrentPoint.x+size.cx+7, rCurrentPoint.y+size.cy+2);

 //Draw Tooltip Rect and Text
 //
 pDC->SetBkMode(TRANSPARENT);
 CBrush brushToolTip(GetSysColor(COLOR_INFOBK));
 pOldBrush = pDC->SelectObject(&brushToolTip);

 //Create and select thick black pen
 CPen penBlack(PS_SOLID, 0, COLORREF(RGB(0, 0, 0)));
 CPen* pOldPen = pDC->SelectObject(&penBlack);

 //Draw rectangle filled with COLOR_INFOBK
 pDC->Rectangle(0,0,rectToolTip.Width(),rectToolTip.Height());

 //Draw tooltip text
    pDC->SetTextColor( GetSysColor(COLOR_INFOTEXT) );//Tool Tip color set in control panel settings
 pDC->SetTextAlign(TA_LEFT);
 pDC->TextOut(3,1, m_szText);

 CRect rectWnd = rectToolTip;
 m_pParentWnd->ClientToScreen(rectWnd); //Convert from client to screen coordinates
 CPoint ptToolTipLeft = rectWnd.TopLeft();

 //Now display tooltip
 SetWindowPos(&wndTop,ptToolTipLeft.x+1, ptToolTipLeft.y+1, rectWnd.Width(),rectWnd.Height(),SWP_SHOWWINDOW|SWP_NOOWNERZORDER|SWP_NOACTIVATE);

 //put back old objects
 pDC->SelectObject(pOldBrush);
 pDC->SelectObject(pOldPen);
 pDC->SelectObject(pOldFont);

 ReleaseDC(pDC);
}

 

 

 

 

 

 

 

 

 

 

 

CTOOLTIPCTRL

 

CToolTipCtrl应用

VC++ 2010-03-13 11:49:18 阅读420 评论1   字号:大中小 订阅

使用CtoolTipCtrl

 

导读:本文适用于相对静止的控件,比如按钮,不适用于向树型控件这样的位置不固定的控件(因为树型控件经常被折叠和展开)

 

CtoolTipCtrl封装了一个工具提示的控件,可弹出一个单行的小窗口来显示一些描述信息,大多时候它是隐藏的,除非用户将光标移到要显示提示的工具上面,并且停留大概半秒的时间它才显示,当单击鼠标或者移走光标的时候这个提示窗口就会消失

 

例子:给对话框的按钮添加提示功能

具体步骤:

 

1 首先创建一个对话框程序TestToolTip

2 在TestToolTip类中定义一个CtoolTipCtrl对象

public:

    CToolTipCtrl m_pToolTipCtrl; 

3 创建一个工具提示控件并关联到m_pToolTipCtrl对象,(位置:OnInitDialog)

 

风格-意义

TTS_ALWAYSTIP

 指示当光标在一个工具上时显示工具提示,不管工具提示的属主窗口是否是处于活动状态。没有这个风格,则只有当工具的属主窗口是活动的时候才会显示工具提示控件,否则不显示

TTS_NOPREFIX

 这个风格禁止系统将 & 字符从一个字符串中去掉。如果一个工具提示控件没有 TTS_NOPREFIX 风格,则系统自动去掉 & 字符,让应用程序用同一个字符串作为菜单项和工具提示控件中的文本

  

if (!m_pToolTipCtrl.Create(this, TTS_ALWAYSTIP))

    {

       TRACE(_T("Unable To create ToolTip/n"));

       return FALSE;

    }

 

4 调用AddTool向工具提示添加注册,这样当光标移动到工具上才能显示信息

    m_pToolTipCtrl.AddTool(GetDlgItem(IDOK),_T("确定按钮,点击关闭对话框")); 

5 添加虚函数PreTranslateMessage 

BOOL CTestToolTipDlg::PreTranslateMessage(MSG* pMsg)

{

    // TODO: Add your specialized code here and/or call the base class

    if(pMsg->message== WM_LBUTTONDOWN ||

       pMsg->message== WM_LBUTTONUP ||

       pMsg->message== WM_MOUSEMOVE)

       m_pToolTipCtrl.RelayEvent(pMsg);

    return CDialog::PreTranslateMessage(pMsg);

}

 

动态改变ToolTip的显示内容的方法及步骤:

 

上面所讲的1、2、4步骤。

在增加ToolTip时不指定显示的字串,而是使用LPSTR_TEXTCALLBACK。

在窗口中增加消息映射 ON_NOTIFY_EX( TTN_NEEDTEXT, 0, SetTipText )。

在窗口中增加一个函数用于动态提供显示内容,其原型为 BOOL SetTipText( UINT id, NMHDR * pTTTStruct, LRESULT * pResult ),下面的代码可以根据传入的参数判定应该显示的内容。

BOOL CWndYour::SetTipText( UINT id, NMHDR * pTTTStruct, LRESULT * pResult )

{

TOOLTIPTEXT *pTTT = (TOOLTIPTEXT *)pTTTStruct;   

UINT nID =pTTTStruct->idFrom; //得到相应窗口ID,有可能是HWND

if (pTTT->uFlags & TTF_IDISHWND)    //表明nID是否为HWND

{

         nID = ::GetDlgCtrlID((HWND)nID);//从HWND得到ID值,当然你也可以通过HWND值来判断

switch(nID)

case(IDC_YOUR_CONTROL1)       

   strcpy(pTTT->lpszText,your_string1);//设置

   return TRUE;

break;

case(IDC_YOUR_CONTROL2)

   //设置相应的显示字串

   return TRUE;

break;

}

return TRUE;

}

 

CToolTipCtrl类成员

构造 CToolTipCtrl 创建一个CToolTipCtrl对象

Create 创建一个工具提示控件并将它与一个CToolTipCtrl对象连接属性

GetText 获取一个工具提示控件为一个工具维持的文本

GetToolInfo 获取一个工具提示控件维持的关于一个工具的信息

SetToolInfo 设置一个工具提示控件为一个工具维持的文本

GetToolCount 获取由一个工具提示控件支持的工具数

GetDelayTime 获取当前为一个工具提示控件设置的初始,弹出,和再显示持续时间

SetDelayTime 为一个工具提示控件设置初始,弹出,和再显示持续时间

GetMargin 获取当前为一个工具提示窗口设置的上,左,底,和右边距

SetMargin 为一个工具提示窗口设置上,左,底,和右边距

GetMaxTipWidth 获取一个工具提示窗口的最大宽度

SetMaxTipWidth 设置一个工具提示窗口的最大宽度

GetTipBkColor 获取一个工具提示窗口中的背景颜色

SetTipBkColor 设置一个工具提示窗口中的背景颜色

GetTipTextColor 获取一个工具提示窗口中的文本颜色

SetTipTextColor 设置一个工具提示窗口中的文本颜色

操作 Activate 激活工具提示控件或使它成为不活动的

AddTool 向一个工具提示控件注册一个工具

DelTool 从工具提示控件中删除一个工具

HitTest 测试一个点,以确定它是否位于给定工具的边界矩形之内,如果是,返回关于这个工具的信息

RelayEvent 传递一个鼠标消息给工具提示控件处理

SetToolRect 为一个工具设置一个新的边界矩形

UpdateTipText 为一个工具设置工具提示文本

Update 强制当前工具被重画

Pop 从视中删除一个被显示的工具提示窗口

 

CToolTipCtrl 只显示一次的解决问题

我最近在编写CToolTipCtrl时 只显示一次的解决问题

在鼠标单击事件的时候再次使用

CToolTipCtrl.Pop();

方法即可

或用ShowWindow(SW_SHOW); 但是这个会出现傻顿现象

/

如果你需要对对话框上的一个按钮进行鼠标停靠提示,那么这么做:

1.      在这个对话框的定义部分添加黑体部分:

class CMyDlg : public CDialog

{

……

CToolTipCtrl m_tt;

……

}

2.      在这个对话框的OnInitDialog()函数里,添加黑体部分:

BOOL CMyDlg::OnInitDialog()

{

……

   EnableToolTips(TRUE);

     m_tt.Create(this);

     m_tt.Activate(TRUE);

     m_tt.AddTool(GetDlgItem(IDC_BUTTON1),"这是一个按钮");

 

//IDC_BUTTON1是需要进行提示的按钮的ID值,这个函数的原型是

 

BOOL AddTool( CWnd* pWnd, LPCTSTR lpszText = LPSTR_TEXTCALLBACK, LPCRECT lpRectTool = NULL, UINT_PTR nIDTool = 0 );

 

       m_tt.SetTipTextColor(RGB(0,0,255)); //提示文字颜色,非必需

       m_tt.SetDelayTime(150);    //出现提示前的延迟时间,非必需

……

}

 

3.重载对话框的PreTranslateMessage(MSG* pMsg)函数,添加黑体部分:

BOOL CMyDlg::PreTranslateMessage(MSG* pMsg)

{

   m_tt.RelayEvent(pMsg);

   return CDialog::PreTranslateMessage(pMsg);

}



http://www.ppmy.cn/news/623311.html

相关文章

pcie干货系列之-TLP’s size/TLP fail/4K boundary/requs

1.The TLP’s size limits are set at the peripheral’s configuration stage, but typical numbers are a maximum of 128, 256 or 512 bytes per TLP,注意pcie的tlp的帧头格式是按照DW为单位的。所以字节都要换算成双字&#xff08;32bit&#xff09;&#xff0c;即[MSB:2],…

Plx使用手册学习------3 PlxPci_DmaTransferBlock

Syntax: PLX_STATUS PlxPci_DmaTransferBlock( PLX_DEVICE_OBJECT *pDevice, U8 channel, PLX_DMA_PARAMS *pDmaParams, U64 Timeout_ms ); PLX Chip Support: 9054, 9056, 9080*, 9656, 8311, & 8000 DMA Description:为给定的DMA通道启动块DMA传输 Starts a Block DMA t…

[CPLEX簡要]2

[CPLEX簡要] cplex.txt是一些名詞的簡略說明 而CPLEX簡要安裝如下~~ 在CPLEX的光碟中&#xff0c;您必須安裝兩項程式 : AMPL CPLEX 及 ILOG license manager AMPL CPLEX是simulation的執行環境&#xff0c;此外還必須安裝 ILOG license manager 才能執行AMPL CPLEX 安裝好lice…

PAT甲级 1010 Radix

PAT甲级 1010 Radix Given a pair of positive integers, for example, 6 and 110, can this equation 6 110 be true? The answer is yes, if 6 is a decimal number and 110 is a binary number. Now for any pair of positive integers N1 and N​2​​ , your task is …

关于P-TMSI和TLLI

P-TMSI是属于GMM层的一个参数&#xff0c;通常包含在GMM层的一些消息里面&#xff0c;如Attach request、Attach accept、Routing area update request、Routing area update accept等等。而TLLI是属于LLC层&#xff08;逻辑链路控制层&#xff09;的一个临时逻辑链路标识符&am…

pat 甲级 1010 Radix (25 point(s))

1010 Radix (25 point(s)) Given a pair of positive integers, for example, 6 and 110, can this equation 6 110 be true? The answer is yes, if 6 is a decimal number and 110 is a binary number. Now for any pair of positive integers N1​ and N2​, your task …

Pareto Principle

最近在看ICDE2021的调优文章时发现出现了大量的Pareto Set的理论&#xff0c;这里记录一下。 一、Pareto理论 由意大利经济学家维弗雷多帕雷托 (Villefredo Pareto)&#xff08;图1&#xff09;在1987年提出&#xff1a;社会财富的80%是掌握在20%的人手中&#xff0c;而余下的…

PAT 1010 Radix (25 分)

1010 Radix (25 分) 今天给大家分享的是PAT甲级的一道小题&#xff0c;求进制。 原题请点击我 简单翻译&#xff1a; 给你两个数字&#xff0c;告诉你一个数的进制是多少&#xff0c;问&#xff0c;另一个数是否在某个进制下和第一个数相等。如果存在&#xff0c;就输出这个进…