一般是不用右键,因为一些控件响影右键消息。给你一个编程百例上的例子,浮动的鼠标提示。 要点楼上已指出。就是在PreTranslateMessage中判断WM——MOUSEMOVE用WindowFromPoint或ChildWindowFromPoint将Point 转化为HWND,通过HWND得到控件ID,通过ID查数组,根据数组信息显示字符。 1、建一个对话框应用程序InfoTip; 2、随便加几个控件。 3、加一个CMFECToolTip对象m_toolTip; 4、将要显示的信息告诉CMFECToolTip对象,在OnInitDialog()中; BOOL CInfoTipDlg::OnInitDialog() { CDialog::OnInitDialog(); // Add "About..." menu item to system menu. // IDM_ABOUTBOX must be in the system command range. ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOX < 0xF000); CMenu* pSysMenu = GetSystemMenu(FALSE); if (pSysMenu != NULL) { CString strAboutMenu; strAboutMenu.LoadString(IDS_ABOUTBOX); if (!strAboutMenu.IsEmpty()) { pSysMenu->AppendMenu(MF_SEPARATOR); pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); } } // Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon
#ifndef _MFECTOOLTIP_H_ #define _MFECTOOLTIP_H_ // default tooltip colors #define IVORY RGB(255, 255, 220) #define BLACK RGB(0, 0, 0)// this structure holds all the tooltip information struct ToolTipInfo : public CObject { UINT nControlID; // ID of the control UINT nInfoSize; // number of lines in the info CStringArray nControlInfo; // container of the information COLORREF nTextColor; // text color COLORREF nBackColor; // background color };class CMFECToolTip : public CWnd { // Construction public: CMFECToolTip(); // standard constructor virtual ~CMFECToolTip(); // destructor void Create(CWnd* pWnd); void ErasePreviousToolTipDisplay( UINT ); void ShowToolTip( UINT ); // explicitly shown the tooltip given the control ID // NOTE: the user must override the PreTranslateMessage in the calling window in order // to handle mousemovent. void ShowToolTip( CPoint& ); // called only during Mousemovement // tooltip functions BOOL AddControlInfo( UINT, CStringArray&, COLORREF back=IVORY, COLORREF text=BLACK ); BOOL RemoveControlInfo( UINT ); // inline functions void SetFontSize( int size ) { m_nFontSize = size; }// Implementation protected: CWnd* m_pParentWnd; int m_nHeight; int m_nWidth; int m_nFontSize; int m_nTotalLine; int m_maxCharInLine; virtual void CalculateInfoBoxRect(UINT nControlID, CRect* pInfoRect); virtual void CalculateHeightAndWidth(CStringArray& straInfos);private: ToolTipInfo* IsControlIDExisting( UINT ); void DisplayInfo( ToolTipInfo* );private: CObArray m_aControlInfo; UINT m_currentControlID; }; #endif
//CMFECToolTip.CPP #include "stdafx.h" #include "MFECToolTip.h"#ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif///////////////////////////////////////////////////////////////////////////// // CMFECToolTipCMFECToolTip::CMFECToolTip() { m_nHeight = 0; m_nWidth = 0; m_nFontSize = 14; // original size m_currentControlID = 0; m_pParentWnd = NULL; m_aControlInfo.RemoveAll(); }CMFECToolTip::~CMFECToolTip() { ToolTipInfo *pInfo = NULL; int nSize = m_aControlInfo.GetSize(); for( int i = 0; i < nSize; i++ ) { pInfo = (ToolTipInfo*)m_aControlInfo.GetAt( i ); delete pInfo; } m_aControlInfo.RemoveAll(); }void CMFECToolTip::Create(CWnd* pWnd) { m_pParentWnd = pWnd; }void CMFECToolTip::ErasePreviousToolTipDisplay( UINT nControlID ) { //This assertion fails because you did not call Create() first. //m_pParentWnd was not initialized. ASSERT(m_pParentWnd); //if erase already, do not do it again if((m_nHeight == 0) || (m_nWidth == 0)) return;
CRect oInfoRect(0,0,0,0); CalculateInfoBoxRect(nControlID, &oInfoRect); m_pParentWnd->InvalidateRect(&oInfoRect); m_pParentWnd->UpdateWindow(); m_nHeight = 0; m_nWidth = 0; } void CMFECToolTip::CalculateHeightAndWidth(CStringArray& straInfos) { //This assertion fails because you did not call Create() first. //m_pParentWnd was not initialized. ASSERT(m_pParentWnd); int nMaxLength = 0; int nLength; int nLine = straInfos.GetSize(); m_nTotalLine = nLine; // holder for maximum line of information for(int i=0; i<nLine; i++) { nLength = (straInfos[i]).GetLength(); if(nLength > nMaxLength) nMaxLength = nLength; } m_maxCharInLine = nMaxLength; // holder for longest char info m_nHeight = 12 + nLine * (m_nFontSize - 1); //m_nFontSize is the font size m_nWidth = 10 + (int)(7.5 * nMaxLength); //aproximately 5 pixel per char } void CMFECToolTip::CalculateInfoBoxRect(UINT nControlID, CRect* pInfoRect) { ASSERT(m_pParentWnd);
PreTranslateMessage函数,截获WM_RBUTTONDOWN消息
然后把鼠标坐标传给Dlg类,并根据每个控件的矩形区域,判断鼠标坐标落在哪个控件上
剩下提示就简单了
然后GetCursorPos获得鼠标位置,判断属于哪个控件
POINT Point
);
要点楼上已指出。就是在PreTranslateMessage中判断WM——MOUSEMOVE用WindowFromPoint或ChildWindowFromPoint将Point 转化为HWND,通过HWND得到控件ID,通过ID查数组,根据数组信息显示字符。
1、建一个对话框应用程序InfoTip;
2、随便加几个控件。
3、加一个CMFECToolTip对象m_toolTip;
4、将要显示的信息告诉CMFECToolTip对象,在OnInitDialog()中;
BOOL CInfoTipDlg::OnInitDialog()
{
CDialog::OnInitDialog(); // Add "About..." menu item to system menu. // IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000); CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
} // Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
m_toolTip.Create( this );
CStringArray straInfo; straInfo.RemoveAll();
straInfo.Add( "Button Control" );
m_toolTip.AddControlInfo( IDC_BUTTON1, straInfo, RGB(0,0,255), RGB( 255,0,192) ); straInfo.RemoveAll();
straInfo.Add( "Test Control" );
m_toolTip.AddControlInfo( IDC_TEXT1, straInfo, RGB(255,255,0) ); straInfo.RemoveAll();
straInfo.Add( "ComboBox Control" );
straInfo.Add( "Data in the lists:" );
straInfo.Add( "Data 1" );
straInfo.Add( "Data 2" );
m_toolTip.AddControlInfo( IDC_COMBO1, straInfo, RGB(192,0,192) ); straInfo.RemoveAll();
straInfo.Add( "Edit Control" );
m_toolTip.AddControlInfo( IDC_EDIT1, straInfo, RGB(192,192,192), RGB( 0,0,255) ); return TRUE; // return TRUE unless you set the focus to a control
}
5、在PreTranslateMessage中加;
BOOL CInfoTipDlg::PreTranslateMessage(MSG* pMsg)
{
if( pMsg->message == WM_MOUSEMOVE )
{
POINT pt = pMsg->pt;
ScreenToClient( &pt );
m_toolTip.ShowToolTip( (CPoint)pt );
}
return CDialog::PreTranslateMessage(pMsg);
}
#define _MFECTOOLTIP_H_
// default tooltip colors
#define IVORY RGB(255, 255, 220)
#define BLACK RGB(0, 0, 0)// this structure holds all the tooltip information
struct ToolTipInfo : public CObject
{
UINT nControlID; // ID of the control
UINT nInfoSize; // number of lines in the info
CStringArray nControlInfo; // container of the information
COLORREF nTextColor; // text color
COLORREF nBackColor; // background color
};class CMFECToolTip : public CWnd
{
// Construction
public:
CMFECToolTip(); // standard constructor
virtual ~CMFECToolTip(); // destructor void Create(CWnd* pWnd);
void ErasePreviousToolTipDisplay( UINT );
void ShowToolTip( UINT ); // explicitly shown the tooltip given the control ID // NOTE: the user must override the PreTranslateMessage in the calling window in order
// to handle mousemovent.
void ShowToolTip( CPoint& ); // called only during Mousemovement // tooltip functions
BOOL AddControlInfo( UINT, CStringArray&, COLORREF back=IVORY, COLORREF text=BLACK );
BOOL RemoveControlInfo( UINT ); // inline functions
void SetFontSize( int size ) { m_nFontSize = size; }// Implementation
protected:
CWnd* m_pParentWnd;
int m_nHeight;
int m_nWidth;
int m_nFontSize; int m_nTotalLine;
int m_maxCharInLine; virtual void CalculateInfoBoxRect(UINT nControlID, CRect* pInfoRect);
virtual void CalculateHeightAndWidth(CStringArray& straInfos);private:
ToolTipInfo* IsControlIDExisting( UINT );
void DisplayInfo( ToolTipInfo* );private:
CObArray m_aControlInfo;
UINT m_currentControlID;
};
#endif
#include "stdafx.h"
#include "MFECToolTip.h"#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif/////////////////////////////////////////////////////////////////////////////
// CMFECToolTipCMFECToolTip::CMFECToolTip()
{
m_nHeight = 0;
m_nWidth = 0;
m_nFontSize = 14; // original size
m_currentControlID = 0;
m_pParentWnd = NULL; m_aControlInfo.RemoveAll();
}CMFECToolTip::~CMFECToolTip()
{
ToolTipInfo *pInfo = NULL;
int nSize = m_aControlInfo.GetSize();
for( int i = 0; i < nSize; i++ )
{
pInfo = (ToolTipInfo*)m_aControlInfo.GetAt( i );
delete pInfo;
} m_aControlInfo.RemoveAll();
}void CMFECToolTip::Create(CWnd* pWnd)
{
m_pParentWnd = pWnd;
}void CMFECToolTip::ErasePreviousToolTipDisplay( UINT nControlID )
{
//This assertion fails because you did not call Create() first.
//m_pParentWnd was not initialized.
ASSERT(m_pParentWnd); //if erase already, do not do it again
if((m_nHeight == 0) || (m_nWidth == 0))
return;
CRect oInfoRect(0,0,0,0); CalculateInfoBoxRect(nControlID, &oInfoRect);
m_pParentWnd->InvalidateRect(&oInfoRect);
m_pParentWnd->UpdateWindow(); m_nHeight = 0;
m_nWidth = 0;
}
void
CMFECToolTip::CalculateHeightAndWidth(CStringArray& straInfos)
{
//This assertion fails because you did not call Create() first.
//m_pParentWnd was not initialized.
ASSERT(m_pParentWnd); int nMaxLength = 0;
int nLength;
int nLine = straInfos.GetSize();
m_nTotalLine = nLine; // holder for maximum line of information
for(int i=0; i<nLine; i++)
{
nLength = (straInfos[i]).GetLength();
if(nLength > nMaxLength)
nMaxLength = nLength;
} m_maxCharInLine = nMaxLength; // holder for longest char info
m_nHeight = 12 + nLine * (m_nFontSize - 1); //m_nFontSize is the font size
m_nWidth = 10 + (int)(7.5 * nMaxLength); //aproximately 5 pixel per char
}
void CMFECToolTip::CalculateInfoBoxRect(UINT nControlID, CRect* pInfoRect)
{
ASSERT(m_pParentWnd);
CRect oRect(0,0,0,0);
CRect oParentWindowRect(0,0,0,0);
m_pParentWnd->GetWindowRect(&oParentWindowRect);
m_pParentWnd->ScreenToClient(&oParentWindowRect);
CWnd* pWnd = m_pParentWnd->GetDlgItem(nControlID);
ASSERT(pWnd);
pWnd->GetWindowRect(&oRect);
m_pParentWnd->ScreenToClient(&oRect);
//check if the box fit in the parent dialog
SetFontSize( 14 );
int nBottom = oRect.bottom - ((oRect.bottom - oRect.top)/2) + m_nHeight;
if(nBottom <= oParentWindowRect.bottom)
{
pInfoRect->top = oRect.bottom - (oRect.bottom - oRect.top)/2;
pInfoRect->bottom = pInfoRect->top + m_nHeight;
}
else
{
// change the size of the font as well as the info box if all
// info data cannot be viewed
if( m_nHeight > (oParentWindowRect.bottom - oParentWindowRect.top) )
{
SetFontSize( 12 );
m_nHeight = 12 + m_nTotalLine * (m_nFontSize - 1); //m_nFontSize is the font size
m_nWidth = 10 + (int)(7 * m_maxCharInLine);
}
// end
pInfoRect->bottom = oParentWindowRect.bottom - 1;
pInfoRect->top = pInfoRect->bottom - m_nHeight;
} //check if the box fit in the parent dialog
int nRight = (oRect.left + oRect.right)/2 + m_nWidth;
if(nRight <= oParentWindowRect.right)
{
pInfoRect->left = (oRect.left + oRect.right)/2;
pInfoRect->right = pInfoRect->left + m_nWidth;
}
else
{
int nLeft = (oRect.left + oRect.right)/2 - m_nWidth;
if(nLeft <= oParentWindowRect.left)
{
pInfoRect->left = oParentWindowRect.left + 1;
pInfoRect->right = pInfoRect->left + m_nWidth;
}
else
{
pInfoRect->right = (oRect.left + oRect.right)/2;
pInfoRect->left = pInfoRect->right - m_nWidth;
}
} ASSERT(pInfoRect->top <= pInfoRect->bottom);
ASSERT(pInfoRect->left <= pInfoRect->right);
}
void CMFECToolTip::ShowToolTip( UINT nControlID )
{
ToolTipInfo *pToolTip = IsControlIDExisting( nControlID );
if( pToolTip == NULL )
return; DisplayInfo( pToolTip );
}
void CMFECToolTip::ShowToolTip( CPoint& point )
{
CWnd* pWnd = m_pParentWnd->ChildWindowFromPoint(point);
if( pWnd )
{
UINT nControlID = (UINT)pWnd->GetDlgCtrlID();
if( m_currentControlID != nControlID )
{
ErasePreviousToolTipDisplay( m_currentControlID );
ShowToolTip( nControlID );
}
}
}void CMFECToolTip::DisplayInfo( ToolTipInfo* pToolTip )
{
if( pToolTip->nInfoSize <= 0 )
return; ASSERT(m_pParentWnd); CDC* pDC = m_pParentWnd->GetDC(); CRect oInfoRect;
CBrush oBrush, *pOldBrush, oBorderBrush;
int nX, nY;
TEXTMETRIC TM;
int nTextHigh;
CFont oFont, *pOldFont;
CWnd* pWnd = NULL; pDC->SetBkMode(TRANSPARENT);
oBrush.CreateSolidBrush( pToolTip->nBackColor ); pOldBrush = pDC->SelectObject( &oBrush );
pDC->SetTextColor( pToolTip->nTextColor ); //calculate the width and height of the box dynamically
CalculateHeightAndWidth( pToolTip->nControlInfo );
CalculateInfoBoxRect( pToolTip->nControlID, &oInfoRect ); oFont.CreateFont(m_nFontSize, 0, 0, 0, FW_REGULAR, 0, 0, 0, 0, 0, 0, 0, 0, "Courier New");
pOldFont = pDC->SelectObject(&oFont);
pDC->FillRect(&oInfoRect, &oBrush);
pDC->SelectObject(pOldBrush);
oBrush.DeleteObject(); oBorderBrush.CreateSolidBrush( pToolTip->nTextColor );
pOldBrush = pDC->SelectObject(&oBorderBrush);
DrawEdge(pDC->m_hDC, &oInfoRect, BDR_RAISEDINNER | BDR_SUNKENOUTER, BF_RECT);
pDC->SetTextAlign(TA_LEFT);
pDC->GetTextMetrics(&TM);
nTextHigh = TM.tmHeight + TM.tmExternalLeading - 2;
nX = oInfoRect.left + 8;
nY = oInfoRect.top + 5; for( register UINT i = 0; i < pToolTip->nInfoSize; i++)
{
pDC->TextOut(nX, nY, pToolTip->nControlInfo[i]);
nY += m_nFontSize - 1;
} pDC->SelectObject(pOldBrush);
oBorderBrush.DeleteObject();
m_pParentWnd->ReleaseDC(pDC);
}
BOOL CMFECToolTip::AddControlInfo( UINT contolID, CStringArray& straInfo, COLORREF back, COLORREF text )
{
ToolTipInfo *pToolTip = new ToolTipInfo;
ASSERT( pToolTip != NULL ); int nSize = straInfo.GetSize();
if( pToolTip <= 0 ) // no information, don't add to the list and return FALSE
{
delete pToolTip;
return FALSE;
} pToolTip->nControlInfo.RemoveAll();
pToolTip->nInfoSize = nSize;
pToolTip->nControlID = contolID;
for( register int i = 0; i < nSize; i++ )
{
pToolTip->nControlInfo.Add( straInfo[i] );
}
// initialize colors, use default if not supplied
pToolTip->nBackColor = back;
pToolTip->nTextColor = text; // add to the list
m_aControlInfo.Add( pToolTip ); return TRUE;
}ToolTipInfo* CMFECToolTip::IsControlIDExisting( UINT controlID )
{
ToolTipInfo *pToolTip = NULL;
int nSize = m_aControlInfo.GetSize();
for( register int i = 0; i < nSize; i++ )
{
pToolTip = (ToolTipInfo*)m_aControlInfo.GetAt( i );
if( pToolTip->nControlID == controlID ) // if found!
{
m_currentControlID = controlID;
return pToolTip;
}
}
m_currentControlID = 0; // if not found, reset the current control ID to refresh the display return NULL;
}BOOL CMFECToolTip::RemoveControlInfo( UINT controlID )
{
ToolTipInfo *pToolTip = NULL;
int nSize = m_aControlInfo.GetSize();
for( register int i = 0; i < nSize; i++ )
{
pToolTip = (ToolTipInfo*)m_aControlInfo.GetAt( i );
if( pToolTip->nControlID == controlID ) // if found!
{
if( m_currentControlID == controlID )
ErasePreviousToolTipDisplay( m_currentControlID ); m_aControlInfo.RemoveAt( i ); // remove the entry
delete pToolTip;
break; // break from the loop
}
} return TRUE;
}