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

📄 pptooltip.cpp

📁 获取本机Outlook Express和Outlook2000/XP中通讯薄内容的示例源码。
💻 CPP
📖 第 1 页 / 共 5 页
字号:
		if ((nIndexTool == m_nIndexCurrentWnd) && (pt == m_ptOriginal) && IsEnabledIndexTool(nIndexTool))
		{
			PrepareDisplayToolTip(&pt);
			if (m_nTimeAutoPop && !(m_pToolInfo.nBehaviour & PPTOOLTIP_DISABLE_AUTOPOP)) //Don't hide window if autopop is 0
				SetTimer(PPTOOLTIP_HIDE, m_nTimeAutoPop, NULL);
		}
		break;
	case PPTOOLTIP_HIDE:
		TRACE(_T("OnTimerHide\n"));
		if (!IsCursorInToolTip() || 
			!IsVisible() || 
			!(m_pToolInfo.nBehaviour & PPTOOLTIP_NOCLOSE_OVER))
			Pop();
		break;
	}
	
	CWnd::OnTimer(nIDEvent);
}

BOOL CPPToolTip::IsEnabledIndexTool(int nIndex)
{
	return (BOOL)(IsExistTool(nIndex) || (nIndex == PPTOOLTIP_TOOL_HELPER));
}

BOOL CPPToolTip::IsCursorInToolTip() const
{
    ASSERT(m_pParentWnd);
	
    // Is tooltip visible?
    if (!IsVisible() || !IsWindow(m_hWnd))
		return FALSE;
	
    CPoint pt;
    GetCursorPos(&pt);
	
	CPPToolTip * pWnd = (CPPToolTip*)WindowFromPoint(pt);
	
	return (pWnd == this);
}

void CPPToolTip::KillTimers(UINT nIDTimer /* = NULL */)
{
//	TRACE (_T("CPPToolTip::KillTimers\n"));
	if (nIDTimer == NULL)
	{
		KillTimer(PPTOOLTIP_SHOW);
		KillTimer(PPTOOLTIP_HIDE);
	}
	else if (nIDTimer == PPTOOLTIP_SHOW)
		KillTimer(PPTOOLTIP_SHOW);
	else if (nIDTimer == PPTOOLTIP_HIDE)
		KillTimer(PPTOOLTIP_HIDE);
}

void CPPToolTip::PrepareDisplayToolTip(CPoint * pt)
{
	TRACE (_T("CPPToolTip::DisplayToolTip()\n"));
	
	//Fills default members
	if (!(m_pToolInfo.nMask & PPTOOLTIP_MASK_STYLES))
		m_pToolInfo.nStyles = m_nStyles;
	if (!(m_pToolInfo.nMask & PPTOOLTIP_MASK_EFFECT))
	{
		m_pToolInfo.nEffect = m_nEffect;
		m_pToolInfo.nGranularity = m_nGranularity;
	}
	if (!(m_pToolInfo.nMask & PPTOOLTIP_MASK_COLORS))
	{
		m_pToolInfo.crBegin = m_crColor[PPTOOLTIP_COLOR_BK_BEGIN];
		m_pToolInfo.crMid = m_crColor[PPTOOLTIP_COLOR_BK_MID];
		m_pToolInfo.crEnd = m_crColor[PPTOOLTIP_COLOR_BK_END];
	}
	if (!(m_pToolInfo.nMask & PPTOOLTIP_MASK_DIRECTION))
		m_pToolInfo.nDirection = m_nDirection;
	if (!(m_pToolInfo.nMask & PPTOOLTIP_MASK_BEHAVIOUR))
		m_pToolInfo.nBehaviour = m_nBehaviour;
	
	//Send notify
	SendNotify(pt, m_pToolInfo);

	//If string and icon are not exist then exit
	if ((m_pToolInfo.hIcon == NULL) && m_pToolInfo.sTooltip.IsEmpty())
		return;
	
	//calculate the width and height of the box dynamically
    CSize sz = GetTooltipSize(m_pToolInfo.sTooltip);
	m_szTextTooltip = sz; //Stores the real size of the tooltip's text
	
	//Gets size of the current icon
	m_szToolIcon = GetSizeIcon(m_pToolInfo.hIcon);
	if (m_szToolIcon.cx || m_szToolIcon.cy)
	{
		sz.cx += m_szToolIcon.cx;
		if (m_szTextTooltip.cx != 0)
			sz.cx += m_nSizes[PPTTSZ_MARGIN_CX]; //If text is exist then adds separator
		sz.cy = max(m_szToolIcon.cy, sz.cy);
	}

	//Gets size of the tooltip with margins
	sz.cx += m_nSizes[PPTTSZ_MARGIN_CX] * 2;
	sz.cy += m_nSizes[PPTTSZ_MARGIN_CY] * 2 + m_nSizes[PPTTSZ_HEIGHT_ANCHOR];
	if (m_pToolInfo.nStyles & PPTOOLTIP_SHADOW)
	{
		sz.cx += m_nSizes[PPTTSZ_SHADOW_CX];
		sz.cy += m_nSizes[PPTTSZ_SHADOW_CY];
	}
	
	CRect rect (0, 0, sz.cx, sz.cy);
	
#ifdef PPTOOLTIP_USE_SHADE
	//If needed to create the bitmap of the background effect
	switch (m_pToolInfo.nEffect)
	{
	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:
		SetShade(rect, m_pToolInfo.nEffect, m_nGranularity, 5, m_pToolInfo.crBegin);
	}
#endif

	DisplayToolTip(pt, &rect);
}

void CPPToolTip::DisplayToolTip(CPoint * pt, CRect * rect)
{
	//Calculate the placement on the screen
	CalculateInfoBoxRect(pt, rect);

	SetWindowPos(NULL, 
                 rect->left, rect->top,
                 rect->Width() + 2, rect->Height() + 2,
                 SWP_SHOWWINDOW|SWP_NOCOPYBITS|SWP_NOACTIVATE|SWP_NOZORDER);

	CRgn rgnCombo;
	rgnCombo.CreateRectRgn(0, 0, 0, 0);
	if (m_pToolInfo.nStyles & PPTOOLTIP_SHADOW)
	{
		rect->right -= m_nSizes[PPTTSZ_SHADOW_CX];
		rect->bottom -= m_nSizes[PPTTSZ_SHADOW_CY];
	}
	m_rgnToolTip.DeleteObject();
	GetWindowRegion(&m_rgnToolTip, CSize (rect->Width(), rect->Height()), *pt);
	rgnCombo.CopyRgn(&m_rgnToolTip);
	if (m_pToolInfo.nStyles & PPTOOLTIP_SHADOW)
	{
		m_rgnShadow.DeleteObject();
		m_rgnShadow.CreateRectRgn(0, 0, 0, 0);
		m_rgnShadow.CopyRgn(&m_rgnToolTip);
		m_rgnShadow.OffsetRgn(m_nSizes[PPTTSZ_SHADOW_CX], m_nSizes[PPTTSZ_SHADOW_CY]);
		rgnCombo.CombineRgn(&rgnCombo, &m_rgnShadow, RGN_OR);
	}
	SetWindowRgn((HRGN)rgnCombo.Detach(), FALSE);
}

CRect CPPToolTip::GetWindowRegion(CRgn * rgn, CSize sz, CPoint pt)
{
	CRect rect;
	rect.SetRect(0, 0, sz.cx, sz.cy);
	CRgn rgnRect;
	CRgn rgnAnchor;
	CPoint ptAnchor [3];
	ptAnchor [0] = pt;
	ScreenToClient(&ptAnchor [0]);
	
	switch (m_nLastDirection)
	{
	case PPTOOLTIP_LEFT_TOP:
	case PPTOOLTIP_RIGHT_TOP:
		rect.bottom -= m_nSizes[PPTTSZ_HEIGHT_ANCHOR];
		ptAnchor [1].y = ptAnchor [2].y = rect.bottom;
		break;
	case PPTOOLTIP_LEFT_BOTTOM:
	case PPTOOLTIP_RIGHT_BOTTOM:
		rect.top += m_nSizes[PPTTSZ_HEIGHT_ANCHOR];
		ptAnchor [1].y = ptAnchor [2].y = rect.top;
		break;
	}
	
	//Gets the region for rectangle with the text
	if (m_pToolInfo.nStyles & PPTOOLTIP_ROUNDED)
		rgnRect.CreateRoundRectRgn(rect.left, rect.top, rect.right + 1, rect.bottom + 1, 
		m_nSizes[PPTTSZ_ROUNDED_CX], m_nSizes[PPTTSZ_ROUNDED_CY]);
	else rgnRect.CreateRectRgn(rect.left, rect.top, rect.right + 1, rect.bottom + 1);
	
	//Gets the region for anchor
	if (m_pToolInfo.nStyles & PPTOOLTIP_ANCHOR)
	{
		switch (m_nLastDirection)
		{
		case PPTOOLTIP_LEFT_TOP:
		case PPTOOLTIP_LEFT_BOTTOM:
			ptAnchor [1].x = rect.right - m_nSizes[PPTTSZ_MARGIN_ANCHOR];
			ptAnchor [2].x = ptAnchor [1].x - m_nSizes[PPTTSZ_WIDTH_ANCHOR];
			break;
		case PPTOOLTIP_RIGHT_TOP:
		case PPTOOLTIP_RIGHT_BOTTOM:
			ptAnchor [1].x = rect.left + m_nSizes[PPTTSZ_MARGIN_ANCHOR];
			ptAnchor [2].x = ptAnchor [1].x + m_nSizes[PPTTSZ_WIDTH_ANCHOR];
			break;
		}
		rgnAnchor.CreatePolygonRgn(ptAnchor, 3, ALTERNATE);
	}
	else
		rgnAnchor.CreateRectRgn(0, 0, 0, 0);
	
	rgn->CreateRectRgn(0, 0, 0, 0);
	rgn->CombineRgn(&rgnRect, &rgnAnchor, RGN_OR);
	
	rgnAnchor.DeleteObject();
	rgnRect.DeleteObject();
	
	return rect;
}

///////////////////////////////////////////////////
//	Gets the size of the current tooltip text
//
//	Parameters:
//		none
//
//	Return value:
//		Size of current tooltip text
///////////////////////////////////////////////////
CSize CPPToolTip::GetTooltipSize(CString str)
{
	//Gets max windows rectangle
	CRect rect;
	GetWindowRect(&rect);

	//Creates compatibility context device in memory
//	CDC * pDC = GetDC();
	CWindowDC dc(NULL);

	CDC memDC;
	CBitmap bitmap;
	memDC.CreateCompatibleDC(&dc);
//	memDC.CreateCompatibleDC(pDC);
	bitmap.CreateCompatibleBitmap(&dc, rect.Width(), rect.Height());
//	bitmap.CreateCompatibleBitmap(pDC, rect.Width(), rect.Height());
	CBitmap* pOldBitmap = memDC.SelectObject(&bitmap);

	//Prints the string on device context for gets minimal size of the rectangle 
	//of the tooltip
	CSize sz = PrintTitleString(&memDC, rect, str);

	memDC.SelectObject(pOldBitmap);
	memDC.DeleteDC();
	bitmap.DeleteObject();

//	ReleaseDC(pDC);

	//Returns minimal rectangle of the tooltip
	return sz;
}

CSize CPPToolTip::GetSizeIcon(HICON hIcon) const
{
	ICONINFO ii;
	CSize sz (0, 0);

	if (hIcon != NULL)
	{
		// Gets icon dimension
		::ZeroMemory(&ii, sizeof(ICONINFO));
		if (::GetIconInfo(hIcon, &ii))
		{
			sz.cx = (DWORD)(ii.xHotspot * 2);
			sz.cy = (DWORD)(ii.yHotspot * 2);
			//release icon mask bitmaps
			if(ii.hbmMask)
				::DeleteObject(ii.hbmMask);
			if(ii.hbmColor)
				::DeleteObject(ii.hbmColor);
		}
	}
	return sz;
}

///////////////////////////////////////////////////
//	Calculates the real rect for the tooltip with margins
//
//	Parameters:
//		pt		[in] - the mouse coordinates (screen coordinates)
//		sz		[in] - the size of the tooltip text
//
//	Return value:
//		The rectangle when the tooltip will draw (screen coordinates)
///////////////////////////////////////////////////
void CPPToolTip::CalculateInfoBoxRect(CPoint * pt, CRect * rect)
{
	// Use the screen's right edge as the right hand border, not the right edge of the client.
	CWindowDC wdc(NULL);
	CRect rWindow(0, 0, 0, 0);
	rWindow.right = GetDeviceCaps(wdc, HORZRES);// - 8;
	rWindow.bottom = GetDeviceCaps(wdc, VERTRES);// - 8;
/*
	m_szToolIcon = GetSizeIcon(m_pToolInfo.hIcon);
	if (m_szToolIcon.cx || m_szToolIcon.cy)
	{
		sz.cx += m_szToolIcon.cx + m_nSizes[PPTTSZ_MARGIN_CX];
		sz.cy = max(m_szToolIcon.cy, sz.cy);
	}

	//Gets size of the tooltip with margins
	sz.cx += m_nSizes[PPTTSZ_MARGIN_CX] * 2;
	sz.cy += m_nSizes[PPTTSZ_MARGIN_CY] * 2 + m_nSizes[PPTTSZ_HEIGHT_ANCHOR];
	if (m_pToolInfo.nStyles & PPTOOLTIP_SHADOW)
	{
		rWindow.right -= m_nSizes[PPTTSZ_SHADOW_CX];
		rWindow.bottom -= m_nSizes[PPTTSZ_SHADOW_CY];
		sz.cx += m_nSizes[PPTTSZ_SHADOW_CX];
		sz.cy += m_nSizes[PPTTSZ_SHADOW_CY];
	}
*/	
//	CRect rect;
//	rect.SetRect(0, 0, sz.cx, sz.cy);
//	CRect rectCopy = *rect;
	
	//Offset the rect from the mouse pointer
	CPoint ptEnd;
	m_nLastDirection = m_pToolInfo.nDirection;
	
	if (!TestHorizDirection(pt->x, rect->Width(), rWindow.right, m_nLastDirection, rect))
	{
		m_nLastDirection = GetNextHorizDirection(m_nLastDirection);
		TestHorizDirection(pt->x, rect->Width(), rWindow.right, m_nLastDirection, rect);
	}
	if (!TestVertDirection(pt->y, rect->Height(), rWindow.bottom, m_nLastDirection, rect))
	{
		m_nLastDirection = GetNextVertDirection(m_nLastDirection);
		TestVertDirection(pt->y, rect->Height(), rWindow.bottom, m_nLastDirection, rect);
	}

	//Returns the rect of the tooltip
	if ((m_pToolInfo.nStyles & PPTOOLTIP_SHADOW) && 
		((m_nLastDirection == PPTOOLTIP_LEFT_TOP) || (m_nLastDirection == PPTOOLTIP_LEFT_BOTTOM)))
		rect->OffsetRect(m_nSizes[PPTTSZ_SHADOW_CX], m_nSizes[PPTTSZ_SHADOW_CY]);
}

///////////////////////////////////////////////////
//	Gets the next horizontal direction
//
//	Parameters:
//		nDirection		[in] - the current direction
//
//	Return value:
//		The next horizontal direction
///////////////////////////////////////////////////
int CPPToolTip::GetNextHorizDirection(int nDirection) const
{
	switch (nDirection)
	{
	case PPTOOLTIP_LEFT_TOP:
		nDirection = PPTOOLTIP_RIGHT_TOP;
		break;
	case PPTOOLTIP_RIGHT_TOP:
		nDirection = PPTOOLTIP_LEFT_TOP;
		break;
	case PPTOOLTIP_LEFT_BOTTOM:
		nDirection = PPTOOLTIP_RIGHT_BOTTOM;
		break;
	case PPTOOLTIP_RIGHT_BOTTOM:
		nDirection = PPTOOLTIP_LEFT_BOTTOM;
		break;
	}
	return nDirection;
}

///////////////////////////////////////////////////
//	Gets the next vertical direction
//
//	Parameters:
//		nDirection		[in] - the current direction
//
//	Return value:
//		The next vertical direction
///////////////////////////////////////////////////
int CPPToolTip::GetNextVertDirection(int nDirection) const
{
	switch (nDirection)
	{
	case PPTOOLTIP_LEFT_TOP:
		nDirection = PPTOOLTIP_LEFT_BOTTOM;
		break;
	case PPTOOLTIP_LEFT_BOTTOM:
		nDirection = PPTOOLTIP_LEFT_TOP;
		break;
	case PPTOOLTIP_RIGHT_TOP:
		nDirection = PPTOOLTIP_RIGHT_BOTTOM;
		break;
	case PPTOOLTIP_RIGHT_BOTTOM:
		nDirection = PPTOOLTIP_RIGHT_TOP;
		break;
	}
	return nDirection;
}

BOOL CPPToolTip::TestHorizDirection(int x, int cx, int w_cx, int nDirection, LPRECT rect) const
{
	int left,right;
	
	switch (nDirection)
	{
	case PPTOOLTIP_LEFT_TOP:
	case PPTOOLTIP_LEFT_BOTTOM:
		right = ((x + (int)m_nSizes[PPTTSZ_MARGIN_ANCHOR]) > w_cx) ? w_cx : (x + m_nSizes[PPTTSZ_MARGIN_ANCHOR]);
		left = right - cx;
		break;
	case PPTOOLTIP_RIGHT_TOP:
	case PPTOOLTIP_RIGHT_BOTTOM:
		left = (x < (int)m_nSizes[PPTTSZ_MARGIN_ANCHOR]) ? 0 : (x - m_nSizes[PPTTSZ_MARGIN_ANCHOR]);
		right = left + cx;
		break;
	}

	BOOL bTestOk = ((left >= 0) && (right <= w_cx)) ? TRUE : FALSE;
	if (bTestOk)
	{
		rect->left = left;
		rect->right = right;
	}

	return bTestOk;
}

BOOL CPPToolTip::TestVertDirection(int y, int cy, int w_cy, int nDirection, LPRECT rect) const
{
	int top, bottom;

	switch (nDirection)
	{
	case PPTOOLTIP_LEFT_TOP:
	case PPTOOLTIP_RIGHT_TOP:
		bottom = y;
		top = bottom - cy;
		break;
	case PPTOOLTIP_LEFT_BOTTOM:
	case PPTOOLTIP_RIGHT_BOTTOM:
		top = y;
		bottom = top + cy;
		break;
	}

	BOOL bTestOk = ((top >= 0) && (bottom <= w_cy)) ? TRUE : FALSE;
	if (bTestOk)
	{
		rect->top = top;
		rect->bottom = bottom;
	}

	return bTestOk;
}

/////////////////////////////////////////////////////////////////
// Gets the system tooltip's logfont
/////////////////////////////////////////////////////////////////
LPLOGFONT CPPToolTip::GetSystemToolTipFont() const
{
    static LOGFONT LogFont;

    NONCLIENTMETRICS ncm;
    ncm.cbSize = sizeof(NONCLIENTMETRICS);
    if (!SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &ncm, 0))
        return FALSE;

    memcpy(&LogFont, &(ncm.lfStatusFont), sizeof(LOGFONT));

⌨️ 快捷键说明

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