⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pptooltip.cpp

📁 获取本机Outlook Express和Outlook2000/XP中通讯薄内容的示例源码。
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/********************************************************************
	created:	2003/04/12
	created:	12:04:2003   10:50
	file base:	PPTooltip
	file ext:	cpp
	author:		Eugene Pustovoyt
	
	purpose:	
*********************************************************************/
#include "stdafx.h"
#include "PPToolTip.h"

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

/////////////////////////////////////////////////////////////////////////////
// CPPToolTip

CPPToolTip::CPPToolTip()
{
	m_pParentWnd = NULL;

	m_rgnShadow.CreateRectRgn(0, 0, 0, 0);
	m_rgnToolTip.CreateRectRgn(0, 0, 0, 0);
	// m_rgnCombo.CreateRectRgn(0, 0, 0, 0);

	m_ptOriginal.x = -1;
	m_ptOriginal.y = -1;

	m_nIndexCurrentWnd = PPTOOLTIP_TOOL_NOEXIST;
	m_nIndexDisplayWnd = PPTOOLTIP_TOOL_NOEXIST;

	SetDelayTime(TTDT_INITIAL, 500);
	SetDelayTime(TTDT_AUTOPOP, 5000);
	SetNotify(FALSE);
	SetDirection();
	SetBehaviour();
	SetDefaultStyles();
	SetDefaultColors();
	SetDefaultSizes();
	SetEffectBk(PPTOOLTIP_EFFECT_SOLID);
	RemoveAllTools();

	// Register the window class if it has not already been registered.
	WNDCLASS wndcls;
	HINSTANCE hInst = AfxGetInstanceHandle();
	if(!(::GetClassInfo(hInst, PPTOOLTIP_CLASSNAME, &wndcls)))
	{
		// otherwise we need to register a new class
		wndcls.style			= CS_SAVEBITS;
		wndcls.lpfnWndProc		= ::DefWindowProc;
		wndcls.cbClsExtra		= wndcls.cbWndExtra = 0;
		wndcls.hInstance		= hInst;
		wndcls.hIcon			= NULL;
		wndcls.hCursor			= LoadCursor(hInst, IDC_ARROW );
		wndcls.hbrBackground	= NULL;
		wndcls.lpszMenuName		= NULL;
		wndcls.lpszClassName	= PPTOOLTIP_CLASSNAME;

		if (!AfxRegisterClass(&wndcls))
			AfxThrowResourceException();
	}
}

CPPToolTip::~CPPToolTip()
{
	RemoveAllTools();
	RemoveAllNamesOfResource();

	m_nLengthLines.RemoveAll();
	m_nHeightLines.RemoveAll();

	// m_rgnCombo.Detach();
	// m_rgnCombo.DeleteObject();
	m_rgnToolTip.DeleteObject();
	m_rgnShadow.DeleteObject();

	if (IsWindow(m_hWnd))
        DestroyWindow();
}


BEGIN_MESSAGE_MAP(CPPToolTip, CWnd)
	//{{AFX_MSG_MAP(CPPToolTip)
	ON_WM_PAINT()
	ON_WM_TIMER()
	ON_WM_DESTROY()
	ON_WM_KILLFOCUS()
	ON_WM_ERASEBKGND()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()


/////////////////////////////////////////////////////////////////////////////
// CPPToolTip message handlers

BOOL CPPToolTip::Create(CWnd* pParentWnd, BOOL bBalloonSize /* = TRUE */) 
{
	TRACE(_T("CPPToolTip::Create\n"));

	ASSERT_VALID(pParentWnd);

	DWORD dwStyle = WS_POPUP; 
	DWORD dwExStyle = WS_EX_TOOLWINDOW | WS_EX_TOPMOST;
	m_pParentWnd = pParentWnd;

	if (!CreateEx(dwExStyle, PPTOOLTIP_CLASSNAME, NULL, dwStyle, 0, 0, 0, 0, pParentWnd->GetSafeHwnd(), NULL, NULL))
	{
		return FALSE;
	}

	SetDefaultFont();
	SetDefaultSizes(bBalloonSize);
	
	return TRUE;
}

void CPPToolTip::OnDestroy() 
{
	KillTimers();
	
	CWnd::OnDestroy();
}

void CPPToolTip::OnKillFocus(CWnd* pNewWnd) 
{
	CWnd::OnKillFocus(pNewWnd);
	
	Pop();
}

BOOL CPPToolTip::OnEraseBkgnd(CDC* pDC) 
{
	return FALSE;
}

void CPPToolTip::Pop()
{
	if (m_nIndexDisplayWnd == PPTOOLTIP_TOOL_HELPER)
		m_nIndexDisplayWnd = PPTOOLTIP_TOOL_NOEXIST;
	KillTimers();
	ShowWindow(SW_HIDE);
}

BOOL CPPToolTip::PreTranslateMessage(MSG* pMsg) 
{
	RelayEvent(pMsg);
	
	return CWnd::PreTranslateMessage(pMsg);
}

LRESULT CPPToolTip::SendNotify(CPoint * pt, PPTOOLTIP_INFO & ti) 
{ 
	TRACE(_T("CPPToolTip::SendNotify()\n")); 
 	// Make sure this is a valid window  
	if (!IsWindow(GetSafeHwnd())) 
		return 0L; 
  
	// See if the user wants to be notified  
	if (!GetNotify()) 
		return 0L; 
  	
	NM_PPTOOLTIP_DISPLAY lpnm; 
	PPTOOLTIP_INFO tiCopy = ti; 
	FromHandle(ti.hWnd)->ClientToScreen(&tiCopy.rectBounds); 
	m_pParentWnd->ScreenToClient(&tiCopy.rectBounds); 
	lpnm.pt = pt;  
	lpnm.ti = &tiCopy; 
	lpnm.hdr.hwndFrom = m_hWnd; 
	lpnm.hdr.idFrom   = GetDlgCtrlID(); 
	lpnm.hdr.code     = UDM_TOOLTIP_DISPLAY; 
	 
	::SendMessage(m_hNotifyWnd, WM_NOTIFY, lpnm.hdr.idFrom, (LPARAM)&lpnm);  
	CRect rcBound = ti.rectBounds;  
	ti = tiCopy; 
	ti.rectBounds = rcBound;  
	return 0L; 
}

void CPPToolTip::OnPaint() 
{
	if (!IsEnabledIndexTool(m_nIndexCurrentWnd))
		return;

	m_nIndexDisplayWnd = m_nIndexCurrentWnd;
	m_nIndexCurrentWnd = PPTOOLTIP_TOOL_NOEXIST;

	CPaintDC dc(this); // device context for painting

	CRect rect;
	GetClientRect(&rect);
	rect.DeflateRect(0, 0, 1, 1);

	// Create a memory device-context. This is done to help reduce
	// screen flicker, since we will paint the entire control to the
	// off screen device context first.CDC memDC;
	CDC memDC;
	CBitmap bitmap;
	memDC.CreateCompatibleDC(&dc);
	bitmap.CreateCompatibleBitmap(&dc, rect.Width(), rect.Height());
	CBitmap* pOldBitmap = memDC.SelectObject(&bitmap); 
	
	memDC.BitBlt(0, 0, rect.Width(), rect.Height(), &dc, 0,0, SRCCOPY);

	OnDraw(&memDC, rect);

	//Copy the memory device context back into the original DC via BitBlt().
	dc.BitBlt(0, 0, rect.Width(), rect.Height(), &memDC, 0,0, SRCCOPY);
	
	//Cleanup resources.
	memDC.SelectObject(pOldBitmap);
	memDC.DeleteDC();
	bitmap.DeleteObject(); 
}

void CPPToolTip::OnDraw(CDC * pDC, CRect rect)
{
	CBrush brBackground(m_crColor [PPTOOLTIP_COLOR_BK_BEGIN]);
	CBrush brBorder(m_crColor [PPTOOLTIP_COLOR_BORDER]);
	
	pDC->SetBkMode(TRANSPARENT); 

	//Sets clip region of the tooltip and draws the shadow if you need
	if (m_pToolInfo.nStyles & PPTOOLTIP_SHADOW)
	{
		//Draws the shadow for the tooltip
		OnDrawShadow(pDC);
		rect.DeflateRect(0, 0, m_nSizes[PPTTSZ_SHADOW_CX], m_nSizes[PPTTSZ_SHADOW_CY]);
	}
	pDC->SelectClipRgn(&m_rgnToolTip);

	OnDrawBackground(pDC, &rect);

	//Draws the main region's border of the tooltip
	pDC->FrameRgn(&m_rgnToolTip, &brBorder, m_nSizes[PPTTSZ_BORDER_CX], m_nSizes[PPTTSZ_BORDER_CY]);

	//Gets the rectangle to draw the tooltip text
	rect.DeflateRect(m_nSizes[PPTTSZ_MARGIN_CX], m_nSizes[PPTTSZ_MARGIN_CY]);
	if ((m_nLastDirection == PPTOOLTIP_RIGHT_BOTTOM) || (m_nLastDirection == PPTOOLTIP_LEFT_BOTTOM))
		rect.top += m_nSizes[PPTTSZ_HEIGHT_ANCHOR];
	else
		rect.bottom -= m_nSizes[PPTTSZ_HEIGHT_ANCHOR];

	// Draw the icon
	if (m_pToolInfo.hIcon != NULL)
	{
		CPoint ptIcon;
		ptIcon.x = m_nSizes[PPTTSZ_MARGIN_CX];
		ptIcon.y = rect.top;
		if (m_pToolInfo.nStyles & PPTOOLTIP_ICON_VCENTER_ALIGN)
			ptIcon.y = rect.top + (rect.Height() - m_szToolIcon.cy) / 2;
		else if (m_pToolInfo.nStyles & PPTOOLTIP_ICON_BOTTOM_ALIGN)
			ptIcon.y = rect.bottom - m_szToolIcon.cy;
		//First variant
//		pDC->DrawIcon(m_nSizes[PPTTSZ_MARGIN_CX], rect.top + (rect.Height() - m_szToolIcon.cy) / 2, m_pToolInfo.hIcon);

		//Second variant
		pDC->DrawState(ptIcon, m_szToolIcon, m_pToolInfo.hIcon, DSS_NORMAL, (CBrush*)NULL);

		//Third variant
//		DrawIconEx(pDC->m_hDC, ptIcon.x, ptIcon.y, m_pToolInfo.hIcon, m_szToolIcon.cx, 
//			m_szToolIcon.cy, 0, NULL, DI_NORMAL);

		rect.left += m_szToolIcon.cx + m_nSizes[PPTTSZ_MARGIN_CX]; 
	}

	//Aligns tooltip's text
	if (m_pToolInfo.nStyles & PPTOOLTIP_BOTTOM_ALIGN)
		rect.top = rect.bottom - m_szTextTooltip.cy;
	else if (m_pToolInfo.nStyles & PPTOOLTIP_VCENTER_ALIGN)
		rect.top += (rect.Height() - m_szTextTooltip.cy) / 2;

	//Prints the tooltip's text
	PrintTitleString(pDC, rect, m_pToolInfo.sTooltip, FALSE);

	brBackground.DeleteObject();
	brBorder.DeleteObject();
}

void CPPToolTip::OnDrawShadow(CDC * pDC)
{
	CBrush brShadow(m_crColor [PPTOOLTIP_COLOR_SHADOW]);
	//Draws the shadow for the tooltip
	int nRop2Mode = pDC->SetROP2(R2_MASKPEN);
	pDC->FillRgn(&m_rgnShadow, &brShadow);
	pDC->SetROP2(nRop2Mode);
	brShadow.DeleteObject();
}

void CPPToolTip::OnDrawBackground(CDC * pDC, CRect * pRect)
{
	switch (m_pToolInfo.nEffect)
	{
	default:
		pDC->FillSolidRect(pRect, m_crColor[PPTOOLTIP_COLOR_BK_BEGIN]);
		break;
	case PPTOOLTIP_EFFECT_HGRADIENT:
		FillGradient(pDC, pRect, m_crColor[PPTOOLTIP_COLOR_BK_BEGIN], m_crColor [PPTOOLTIP_COLOR_BK_END], TRUE);
		break;
	case PPTOOLTIP_EFFECT_VGRADIENT:
		FillGradient(pDC, pRect, m_crColor[PPTOOLTIP_COLOR_BK_BEGIN], m_crColor [PPTOOLTIP_COLOR_BK_END], FALSE);
		break;
	case PPTOOLTIP_EFFECT_HCGRADIENT:
		FillGradient(pDC, CRect(pRect->left, pRect->top, pRect->left + pRect->Width() / 2, pRect->bottom), 
			m_crColor[PPTOOLTIP_COLOR_BK_BEGIN], m_crColor [PPTOOLTIP_COLOR_BK_END], TRUE);
		FillGradient(pDC, CRect(pRect->left + pRect->Width() / 2, pRect->top, pRect->right, pRect->bottom), 
			m_crColor[PPTOOLTIP_COLOR_BK_END], m_crColor [PPTOOLTIP_COLOR_BK_BEGIN], TRUE);
		break;
	case PPTOOLTIP_EFFECT_VCGRADIENT:
		FillGradient(pDC, CRect (pRect->left, pRect->top, pRect->right, pRect->top + pRect->Height() / 2), 
			m_crColor[PPTOOLTIP_COLOR_BK_BEGIN], m_crColor [PPTOOLTIP_COLOR_BK_END], FALSE);
		FillGradient(pDC, CRect (pRect->left, pRect->top + pRect->Height() / 2, pRect->right, pRect->bottom), 
			m_crColor[PPTOOLTIP_COLOR_BK_END], m_crColor [PPTOOLTIP_COLOR_BK_BEGIN], FALSE);
		break;
	case PPTOOLTIP_EFFECT_3HGRADIENT:
		FillGradient(pDC, CRect(pRect->left, pRect->top, pRect->left + pRect->Width()/2, pRect->bottom), 
			m_crColor[PPTOOLTIP_COLOR_BK_BEGIN], m_crColor [PPTOOLTIP_COLOR_BK_MID], TRUE);
		FillGradient(pDC, CRect(pRect->left + pRect->Width() / 2, pRect->top, pRect->right, pRect->bottom), 
			m_crColor[PPTOOLTIP_COLOR_BK_MID], m_crColor [PPTOOLTIP_COLOR_BK_END], TRUE);
		break;
	case PPTOOLTIP_EFFECT_3VGRADIENT:
		FillGradient(pDC, CRect (pRect->left, pRect->top, pRect->right, pRect->top + pRect->Height() / 2), 
			m_crColor[PPTOOLTIP_COLOR_BK_BEGIN], m_crColor [PPTOOLTIP_COLOR_BK_MID], FALSE);
		FillGradient(pDC, CRect (pRect->left, pRect->top + pRect->Height() / 2, pRect->right, pRect->bottom), 
			m_crColor[PPTOOLTIP_COLOR_BK_MID], m_crColor [PPTOOLTIP_COLOR_BK_END], FALSE);
		break;
#ifdef PPTOOLTIP_USE_SHADE
	case PPTOOLTIP_EFFECT_NOISE:
	case PPTOOLTIP_EFFECT_DIAGSHADE:
	case PPTOOLTIP_EFFECT_HSHADE:
	case PPTOOLTIP_EFFECT_VSHADE:
	case PPTOOLTIP_EFFECT_HBUMP:
	case PPTOOLTIP_EFFECT_VBUMP:
	case PPTOOLTIP_EFFECT_SOFTBUMP:
	case PPTOOLTIP_EFFECT_HARDBUMP:
	case PPTOOLTIP_EFFECT_METAL:
		m_dNormal.Draw(pDC->GetSafeHdc(),0,0);
		break;
#endif
	}
}

void CPPToolTip::RelayEvent(MSG* pMsg)
{
	ASSERT(m_pParentWnd);
	CWnd * pWnd = NULL;
	CPoint pt;
	CRect rect;
	CString str;
	int nIndexTool = PPTOOLTIP_TOOL_NOEXIST;

//	PPTOOLTIP_INFO  Info;
		
	switch(pMsg->message)
	{
	case WM_LBUTTONDOWN:
	case WM_LBUTTONDBLCLK:
	case WM_RBUTTONDOWN:
	case WM_RBUTTONDBLCLK:
	case WM_MBUTTONDOWN:
	case WM_MBUTTONDBLCLK:
	case WM_NCLBUTTONDOWN:
	case WM_NCLBUTTONDBLCLK:
	case WM_NCRBUTTONDOWN:
	case WM_NCRBUTTONDBLCLK:
	case WM_NCMBUTTONDOWN:
	case WM_NCMBUTTONDBLCLK:
	case WM_KEYDOWN:
	case WM_SYSKEYDOWN:
		// The user has interupted the current tool - dismiss it
		Pop();
		break;
	case WM_MOUSEMOVE:
//		TRACE (_T("OnMouseMove()\n"));
		if ((m_ptOriginal == pMsg->pt) || 
			(m_nIndexCurrentWnd == PPTOOLTIP_TOOL_HELPER) ||
			(m_nIndexDisplayWnd == PPTOOLTIP_TOOL_HELPER))
			return; //Mouse pointer was not move

		//Check Active window
		if (!(m_nStyles & PPTOOLTIP_SHOW_INACTIVE))
		{
			pWnd = GetActiveWindow();
			if (!pWnd)
				return;
		}

		m_ptOriginal = pMsg->pt; //Stores the mouse's coordinates
		
		//Gets the real window under the mouse
		pt = pMsg->pt;
		m_pParentWnd->ScreenToClient(&pt);
		
		nIndexTool = FindTool(pt);

		if (!IsExistTool(nIndexTool))
		{
			//If the window under the mouse isn't exist
			if (IsCursorInToolTip() && (m_pToolInfo.nBehaviour & PPTOOLTIP_CLOSE_LEAVEWND))
				return;
			Pop();
			m_nIndexCurrentWnd = PPTOOLTIP_TOOL_NOEXIST;
			m_nIndexDisplayWnd = PPTOOLTIP_TOOL_NOEXIST;
			return;
		}
		else
		{
			//The window under the mouse is exist
			if (nIndexTool == m_nIndexDisplayWnd)
			{
				if (IsVisible())
				{
					//Now the tooltip is visible
					if ((m_pToolInfo.nBehaviour & PPTOOLTIP_CLOSE_LEAVEWND))
						return;
				}
				if (m_pToolInfo.nBehaviour & PPTOOLTIP_MULTIPLE_SHOW)
				{
					SetNewToolTip(nIndexTool);
				}
				else Pop();
			}
			else
			{
				SetNewToolTip(nIndexTool, !IsVisible());
			}
		}
		break;
	}
}

void CPPToolTip::SetNewToolTip(int nIndexTool, BOOL bWithDelay /* = TRUE */)
{
	TRACE (_T("CPPToolTip::SetNewToolTip(Index = 0x%X)\n"), nIndexTool);
	
	m_nIndexDisplayWnd = PPTOOLTIP_TOOL_NOEXIST; //reset the displayed window
	Pop();

	//Gets the info about current tool
	if (!GetTool(nIndexTool, m_pToolInfo))
		return;

	//Remembers the pointer to the current window
	m_nIndexCurrentWnd = nIndexTool;

	//Start the show timer
	if (bWithDelay)
		SetTimer(PPTOOLTIP_SHOW, m_nTimeInitial, NULL);
	else
		OnTimer(PPTOOLTIP_SHOW);
}

void CPPToolTip::OnTimer(UINT nIDEvent) 
{
	CPoint pt = m_ptOriginal, point;
	CString str;
	int nIndexTool = PPTOOLTIP_TOOL_HELPER;

	switch (nIDEvent)
	{
	case PPTOOLTIP_SHOW:
		TRACE(_T("OnTimerShow\n"));
		Pop();
		if (m_nIndexCurrentWnd != PPTOOLTIP_TOOL_HELPER)
		{
			GetCursorPos(&pt);
			point = pt;
			m_pParentWnd->ScreenToClient(&point);
			nIndexTool = FindTool(point);
		}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -