创建方法
CXInfoTipWhenHit* g_pInfoTip;
//在入口处创建 g_pInfoTip = new CXInfoTipWhenHit; g_pInfoTip->Create(this);
删除方法
if(g_pInfoTip != NULL) { delete g_pInfoTip; g_pInfoTip = NULL; }
使用方法g_pInfoTip->Show(strMsg);
以下是实现
//头文件
#pragma once /** *显示单击按钮、菜单执行结果的提示框 */ class CXInfoTipWhenHit : public CWnd { protected: /// // Tool information structure /// typedef struct { CString szText; // Tooltip text HICON hIcon; // Tooltip icon } TipToolInfo; // Timer identifiers enum { timerShow = 100, // Show timer timerHide = 101 // Hide timer }; LPCTSTR m_szClass; // Window class int m_nShowDelay; // Show delay CPoint m_ptOrigin; // Popup origin CString m_szText; // Tip text UINT m_nTimer; // Show/hide timer HICON m_hIcon; // Tip icon CSize m_IconSize; // Tip icon size CFont *m_pFont; // Tip font CMap<HWND, HWND, TipToolInfo, TipToolInfo> m_ToolMap; // Tools map public: CXInfoTipWhenHit(); virtual ~CXInfoTipWhenHit(); BOOL Create(CWnd *parent); void AddTool(CWnd *pWnd, LPCTSTR szTooltipText, HICON hIcon = NULL); void RemoveTool(CWnd *pWnd); void Show(CString szText); void Hide(); // Sets the delay for the tooltip void SetShowDelay(int nDelay) { m_nShowDelay = nDelay; }; void SetIcon(HICON hIcon); // Sets the tooltip font void SetFont(CFont *pFont) { m_pFont = pFont; if (IsWindow(m_hWnd)) RedrawWindow(); }; void RelayEvent(LPMSG lpMsg); protected: BOOL GetWindowRegion(CDC *pDC, HRGN* hRegion, CSize* Size = NULL); protected: //{{AFX_MSG(CXInfoTip) afx_msg void OnPaint(); afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); afx_msg void OnTimer(UINT nIDEvent); afx_msg void OnDestroy(); //}}AFX_MSG DECLARE_MESSAGE_MAP() };
//源文件#include "StdAfx.h" #include "XInfoTipWhenHit.h" #define CX_ROUNDED 12 // Tip horizontal roundness #define CY_ROUNDED 10 // Tip vertical roundness #define CX_LEADER 25 // Width of tip lead #define CY_LEADER 25 // Height of tip lead #define CX_ICON_MARGIN 5 // Width of margin between icon and tip text #define DEFAULT_SHOW_DELAY 100 // Default show delay (ms) #define TIMER_HIDE 1000 // Hide timer (ms) / // // CXInfoTip::CXInfoTip() // // DESCRIPTION // // Constructor // / CXInfoTipWhenHit::CXInfoTipWhenHit() { // Register the class m_szClass = AfxRegisterWndClass(0); m_hIcon = NULL; // Set the delay defaults m_nShowDelay = DEFAULT_SHOW_DELAY; m_IconSize = CSize(0, 0); m_ptOrigin = CPoint(0, 0); } / // // CXInfoTip::~CXInfoTip() // // DESCRIPTION // // Deconstructor // / CXInfoTipWhenHit::~CXInfoTipWhenHit() { } // Message map BEGIN_MESSAGE_MAP(CXInfoTipWhenHit, CWnd) //{{AFX_MSG_MAP(CXInfoTip) ON_WM_PAINT() ON_WM_CREATE() ON_WM_TIMER() ON_WM_DESTROY() //}}AFX_MSG_MAP END_MESSAGE_MAP() / // // CXInfoTip::Create() // // DESCRIPTION // // Creates the tip window // // RETURNS // // [BOOL] - TRUE on success, FALSE on failure // // PARAMETERS // // [pParentWnd] - Pointer to parent window // / BOOL CXInfoTipWhenHit::Create(CWnd* pParentWnd) { BOOL bSuccess; // Must have a parent ASSERT(pParentWnd != NULL); bSuccess = CreateEx(NULL, m_szClass, NULL, WS_POPUP, 0, 0, 0, 0, pParentWnd->GetSafeHwnd(), NULL, NULL); // Use default GUI font for default font m_pFont = pParentWnd->GetFont(); return bSuccess; } / // // CXInfoTip::Show() // // DESCRIPTION // // Shows the tip window // // RETURNS // // [void] // // PARAMETERS // // [szText] - Tip text // [pt] - Coordinates to display tip window // or NULL to use the current cursor position // / void CXInfoTipWhenHit::Show(CString szText) { GetCursorPos(&m_ptOrigin); m_szText = szText; // Start the show timer m_nTimer = SetTimer(timerShow, m_nShowDelay, NULL); } / // // CXInfoTip::OnPaint() // // DESCRIPTION // // Paint the window // // RETURNS // // [void] // / void CXInfoTipWhenHit::OnPaint() { CPaintDC dc( this ); // device context for painting CRect rc; CBrush WindowBrush; CBrush FrameBrush; CBrush InnerFrameBrush; HRGN hRegion; CRgn *pRegion; CFont *pSysFont; // Get the client rectangle GetClientRect(rc); // Create the brushes InnerFrameBrush.CreateSolidBrush(::GetSysColor(COLOR_SCROLLBAR)); FrameBrush.CreateSolidBrush(::GetSysColor(COLOR_WINDOWTEXT)); WindowBrush.CreateSolidBrush(::GetSysColor(COLOR_WINDOW)); // Get the window region GetWindowRegion(&dc, &hRegion); pRegion = CRgn::FromHandle(hRegion); // Draw the frame dc.FillRgn(pRegion, &WindowBrush); dc.FrameRgn(pRegion, &InnerFrameBrush, 3, 3); dc.FrameRgn(pRegion, &FrameBrush, 1, 1); // Adjust the area for the icon rc.DeflateRect(CX_ROUNDED, CY_ROUNDED, 0, 0); if (m_hIcon != NULL) rc.left = rc.left + m_IconSize.cx + CX_ICON_MARGIN; // Set the font pSysFont = (CFont *)dc.SelectObject(m_pFont); // Draw the tip text dc.SetBkMode( TRANSPARENT ); dc.DrawText(m_szText, &rc, DT_TOP | DT_LEFT); // Draw the icon if (m_hIcon != NULL) DrawIconEx(dc.m_hDC, CX_ROUNDED, CY_ROUNDED, m_hIcon, m_IconSize.cx, m_IconSize.cy, 0, NULL, DI_NORMAL); // Clean up GDI ::DeleteObject(hRegion); dc.SelectObject(pSysFont); } / // // CXInfoTip::GetWindowRegion() // // DESCRIPTION // // Retrieves the window region // // RETURNS // // [BOOL] - TRUE on success, FALSE on failure // // PARAMETERS // // [pDC] - Pointer to display device context // [hRegion] - Filled with the calculated window region // [Size] - Filled with the calculated window size // or NULL. // / BOOL CXInfoTipWhenHit::GetWindowRegion(CDC* pDC, HRGN* hRegion, CSize *Size /* = NULL */) { CRect rcWnd; POINT ptLeader[3]; CRgn LeaderRegion; CRgn CaptionRegion; CFont *pSysFont; ASSERT(pDC != NULL); ASSERT(hRegion != NULL); // Calculate the are for the tip text pSysFont = (CFont *)pDC->SelectObject(m_pFont); pDC->DrawText(m_szText, &rcWnd, DT_CALCRECT); pDC->SelectObject(pSysFont); // Adjust for the rounded corners rcWnd.InflateRect(CX_ROUNDED, CY_ROUNDED); // Adjust for icon if (m_hIcon != NULL) rcWnd.right = rcWnd.right + m_IconSize.cx + CX_ICON_MARGIN; if (rcWnd.Height() < m_IconSize.cy) rcWnd.bottom = rcWnd.top + m_IconSize.cy; int xCord= m_ptOrigin.x - rcWnd.Width() + CX_ROUNDED; int nOffset= 0; if (xCord < 0 ){ nOffset= xCord; } // Calculate the leader triangle coordinates ptLeader[0].x = rcWnd.Width() - CX_ROUNDED+ nOffset; ptLeader[0].y = rcWnd.Height() - CY_ROUNDED; ptLeader[1].x = ptLeader[0].x; ptLeader[1].y = ptLeader[0].y + CY_LEADER; ptLeader[2].x = ptLeader[0].x - CX_LEADER; ptLeader[2].y = rcWnd.Height() - CY_ROUNDED; // Create the caption region CaptionRegion.CreateRoundRectRgn(0, 0, rcWnd.Width(), rcWnd.Height(), CX_ROUNDED, CY_ROUNDED); // Create the leader region LeaderRegion.CreatePolygonRgn(ptLeader, 3, ALTERNATE); // Create window region *hRegion = ::CreateRectRgn(0, 0, rcWnd.Width(), rcWnd.Height() + CY_LEADER); // Combine the regions CombineRgn(*hRegion, CaptionRegion.operator HRGN(), LeaderRegion.operator HRGN(), RGN_OR); // Set the window size if (Size != NULL) { Size->cx = rcWnd.Width(); Size->cy = rcWnd.Height() + CY_LEADER; } return TRUE; } / // // CXInfoTip::OnCreate() // // DESCRIPTION // // Window creation // // RETURNS // // [int] - Zero on success, -1 otherwise // // PARAMETERS // // [lpCreateStruct] - Pointer to creation structure // / int CXInfoTipWhenHit::OnCreate( LPCREATESTRUCT lpCreateStruct ) { if ( CWnd::OnCreate( lpCreateStruct ) == -1 ) return -1; return 0; } / // // CXInfoTip::OnTimer() // // DESCRIPTION // // Timer event // // RETURNS // // [void] // // PARAMETERS // // [nIDEvent] - Timer identifier // / void CXInfoTipWhenHit::OnTimer( UINT nIDEvent ) { HRGN hRegion; CSize WindowSize; CDC *pDC; CPoint ptCursor; switch (nIDEvent) { / // Show the tip window / case timerShow: { KillTimer(m_nTimer); ShowWindow(SW_HIDE); pDC = GetDC(); GetWindowRegion(pDC, &hRegion, &WindowSize); ReleaseDC(pDC); ::SetWindowRgn(m_hWnd, hRegion, TRUE); POINT pointWnd; pointWnd.x= m_ptOrigin.x - WindowSize.cx + CX_ROUNDED; pointWnd.y= m_ptOrigin.y - WindowSize.cy + CY_ROUNDED; int nOffset= 0; if (pointWnd.x < 0 ){ pointWnd.x= 0; } SetWindowPos(&wndTop, pointWnd.x , pointWnd.y , WindowSize.cx, WindowSize.cy, SWP_NOACTIVATE | SWP_SHOWWINDOW); m_nTimer = SetTimer(timerHide, TIMER_HIDE, NULL); break; } / // Hide the tip window / case timerHide: GetCursorPos(&ptCursor); if (ptCursor != m_ptOrigin) { KillTimer(m_nTimer); ShowWindow(SW_HIDE); } break; } CWnd::OnTimer(nIDEvent); } / // // CXInfoTip::OnDestroy() // // DESCRIPTION // // Window destruction // // RETURNS // // [void] // / void CXInfoTipWhenHit::OnDestroy() { KillTimer(m_nTimer); CWnd::OnDestroy(); } / // // CXInfoTip::RelayEvent() // // DESCRIPTION // // Call this in the parent's PreTranslateMessage() to // relay tooltip event messages. // // RETURNS // // [void] // // PARAMETERS // // [lpMsg] - Pointer to message structure // / void CXInfoTipWhenHit::RelayEvent(LPMSG lpMsg) { CPoint point; CWnd *pWindow; CString szTooltipText; TipToolInfo Info; switch(lpMsg->message) { case WM_LBUTTONDOWN: case WM_RBUTTONDOWN: case WM_MBUTTONDOWN: ShowWindow(SW_HIDE); break; case WM_MOUSEMOVE: GetCursorPos(&point); if (point != m_ptOrigin) { // Find the tool CWnd* pParent= CWnd::FromHandle(lpMsg->hwnd); if (pParent) { POINT ptClient= point; pParent->ScreenToClient(&ptClient); pWindow = pParent->ChildWindowFromPoint(ptClient,CWP_SKIPINVISIBLE); if (pWindow != NULL) { if (m_ToolMap.Lookup(pWindow->m_hWnd, Info)) { // Display the tooltip m_ptOrigin = point; SetIcon(Info.hIcon); Show(Info.szText); } } } } // Hide the tooltip if (point != m_ptOrigin) { Hide(); } break; } } void CXInfoTipWhenHit::Hide() { KillTimer(m_nTimer); ShowWindow(SW_HIDE); }; / // // CXInfoTip::SetIcon() // // DESCRIPTION // // Sets the tip window icon // // RETURNS // // [void] // // PARAMETERS // // [hIcon] - Handle to the icon // / void CXInfoTipWhenHit::SetIcon(HICON hIcon) { ICONINFO IconInfo; m_hIcon = hIcon; if (hIcon == NULL) { m_IconSize = CSize(0, 0); return; } // Get the icon sizes ZeroMemory(&IconInfo, sizeof(ICONINFO)); ::GetIconInfo(m_hIcon, &IconInfo); m_IconSize.cx = (BYTE)(IconInfo.xHotspot * 2); m_IconSize.cy = (BYTE)(IconInfo.yHotspot * 2); ::DeleteObject(IconInfo.hbmMask); ::DeleteObject(IconInfo.hbmColor); if (IsWindow(m_hWnd)) RedrawWindow(); } / // // CXInfoTip::AddTool() // // DESCRIPTION // // Adds a tool // // RETURNS // // [void] // // PARAMETERS // // [pWnd] - Pointer to the tool window // [szTooltipText] - Text to display when the cursor hovers // over the window (pWnd) // [hIcon] - Icon to display in the tooltip, or NULL // to display no icon. // / void CXInfoTipWhenHit::AddTool(CWnd *pWnd, LPCTSTR szTooltipText, HICON hIcon /* = NULL */) { ASSERT(pWnd != NULL); // Store the tool information TipToolInfo Info; Info.szText = szTooltipText; Info.hIcon = hIcon; // Add the tool m_ToolMap.SetAt(pWnd->m_hWnd, Info); }; / // // CXInfoTip::RemoveTool() // // DESCRIPTION // // Removes a tool // // RETURNS // // [void] // // PARAMETERS // // [pWnd] - Pointer to the tool window to remove // / void CXInfoTipWhenHit::RemoveTool(CWnd *pWnd) { m_ToolMap.RemoveKey(pWnd->m_hWnd); }