www.pudn.com > hotel2003.rar > CoolTipCtrl.cpp


/*######################################################################## 
	Filename: 	cooltipctrl.cpp 
	---------------------------------------------------- 
	Remarks:	... 
	---------------------------------------------------- 
	Author:		³ÉÕæ 
	Email:		anyou@sina.com 
				anyou@msn.com 
	Created:	23/3/2003 19:20 
  ########################################################################*/ 
 
#include "stdafx.h" 
#include "CoolTipCtrl.h" 
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
 
#define TIMER_DELAY  1 
#define TIMER_FADE   2 
#define TIMER_PTTEST 3 
 
/*######################################################################## 
						------------------------- 
							    Construction 
						------------------------- 
  ########################################################################*/ 
CCoolTipCtrl::CCoolTipCtrl() 
{ 
	m_nSize		 = CSize(10, 10); 
	m_nFade		 = 0; 
	m_nDelayTime = 10; 
	m_rcRect	 = CRect(0, 0, 8888, 6666); 
	m_crBk		 = RGB(250, 255, 225); 
	m_crText	 = RGB(0, 0, 0); 
	m_crTitle	 = RGB(0, 0, 0); 
	m_hIcon		 = NULL; 
	m_szIcon	 = CSize(0, 0); 
	m_dwState	 = 0; 
} 
 
BOOL CCoolTipCtrl::Create(CSize size, CWnd *pParentWnd, UINT dwStyle, UINT uID) 
{ 
	m_nSize = size; 
	m_dwStyle = dwStyle; 
	return CreateEx(WS_EX_TOOLWINDOW, 
					::AfxRegisterWndClass(0), 
					"COOL_TIP_CTRL_WINDOW", 
					WS_POPUP, 
					CRect(0, 0, size.cx, size.cy), 
					pParentWnd, 
					uID); 
} 
 
CCoolTipCtrl::~CCoolTipCtrl() 
{ 
 
} 
 
/*################################################################ 
				-------------------------------------- 
					CoolTip control message handlers 
				-------------------------------------- 
  ################################################################*/ 
 
BEGIN_MESSAGE_MAP(CCoolTipCtrl, CWnd) 
	//{{AFX_MSG_MAP(CCoolTipCtrl) 
	ON_WM_CREATE() 
	ON_WM_DESTROY() 
	ON_WM_LBUTTONUP() 
	ON_WM_TIMER() 
	ON_WM_PAINT() 
	ON_WM_NCPAINT() 
	ON_WM_NCCALCSIZE() 
	ON_WM_NCHITTEST() 
	//}}AFX_MSG_MAP 
END_MESSAGE_MAP() 
 
int CCoolTipCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct)  
{ 
	if (CWnd::OnCreate(lpCreateStruct) == -1) 
	{ 
		return -1; 
	} 
	 
	CRect rect; 
	GetClientRect(&rect); 
	CDC *pdc = GetDC(); 
	m_MemDC.CreateCompatibleDC(pdc); 
	bitmap.CreateCompatibleBitmap(pdc, m_nSize.cx, m_nSize.cy); 
	oldbitmap = m_MemDC.SelectObject(&bitmap); 
	ReleaseDC(pdc); 
 
	//load dll------------------------------------------------- 
	hUserDll = ::LoadLibrary(_T("USER32.dll")); 
	//Change style to layered window style... 
	::SetWindowLong(m_hWnd, GWL_EXSTYLE, ::GetWindowLong(m_hWnd, GWL_EXSTYLE) | WS_EX_LAYERED); 
	SetTransparent(m_hWnd, 0, 0 , LWA_ALPHA ); 
	 
	return 0; 
} 
 
void CCoolTipCtrl::OnDestroy()  
{ 
	CWnd::OnDestroy(); 
 
	KillTimer(TIMER_FADE); 
	KillTimer(TIMER_DELAY); 
	KillTimer(TIMER_PTTEST); 
 
	m_MemDC.SelectObject(oldbitmap); 
	bitmap.DeleteObject(); 
	m_MemDC.DeleteDC(); 
} 
 
void CCoolTipCtrl::OnLButtonUp(UINT nFlags, CPoint point)  
{ 
	Hide(); 
	CWnd::OnLButtonUp(nFlags, point); 
} 
 
void CCoolTipCtrl::OnTimer(UINT nIDEvent)  
{ 
	switch (nIDEvent)  
	{ 
	//Delay show=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- 
	case TIMER_DELAY: 
		m_nShowTime--; 
		//Delay time over-----------------------------= 
		if (m_nShowTime <= 0) 
		{ 
			//Kill this timer----------------------- 
			KillTimer(TIMER_DELAY); 
 
			//PtTest-------------------------------- 
			::GetCursorPos(&m_point); 
			if (!m_rcRect.PtInRect(m_point)) 
			{ 
				KillTimer(TIMER_PTTEST); 
				m_dwState = TIPS_HIDE; 
				return; 
			} 
 
			//Set size------------------------------ 
			m_point.y += 20; 
			if (m_dwStyle & TIPS_AUTOSIZE) 
			{ 
				AutoSize(); 
			} 
 
			//Captrue Screen for draw shadow-------- 
			CDC dc; 
			dc.Attach(::GetWindowDC(NULL)); 
			m_MemDC.BitBlt(0, 0, m_nSize.cx, m_nSize.cy, &dc, m_point.x, m_point.y, SRCCOPY); 
			dc.Detach(); 
			dc.DeleteDC(); 
 
			//Display tip window--------------------- 
			SetWindowPos(&wndTopMost, 
						 m_point.x,  
						 m_point.y,  
						 m_nSize.cx,  
						 m_nSize.cy, 
						 SWP_SHOWWINDOW | SWP_NOACTIVATE); 
 
			//Draw window memory dc------------------ 
			OnDraw(&m_MemDC); 
			 
			//fade out window------------------------ 
			SetTransparent(m_hWnd, 0, 0 , LWA_ALPHA ); 
			m_dwState = TIPS_FADEOUT; 
			m_nFade = 0; 
			SetTimer(TIMER_FADE, 30, NULL); 
		} 
		break; 
	 
	//Fade out or in window=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 
	case TIMER_FADE: 
		if (m_dwState == TIPS_FADEIN) 
		{ 
			m_nFade -= 28; //Fade in 
		} 
		else if (m_dwState == TIPS_FADEOUT) 
		{ 
			m_nFade += 28; //Fade out 
		} 
 
		if (m_nFade >= 230) 
		{ 
			m_nFade = (m_dwStyle & 0x00000002) ? 230 : 255; 
			m_dwState &= TIPS_NORMAL; 
			KillTimer(TIMER_FADE); 
			SetTimer (TIMER_PTTEST, 500, NULL); 
		} 
		else if (m_nFade < 0) 
		{ 
			//Hide window----------------- 
			m_nFade = 0; 
			m_dwState = TIPS_HIDE; 
			KillTimer(TIMER_FADE); 
			KillTimer(TIMER_PTTEST); 
			ShowWindow(SW_HIDE); 
			if (GetStyle() & TIPS_SHOWNEXT) 
			{ 
				m_dwStyle &= ~TIPS_SHOWNEXT; 
				m_nShowTime = 1; 
				m_dwState	= TIPS_DELAYSHOW; 
				SetTimer(TIMER_DELAY , 100, NULL); 
				SetTimer(TIMER_PTTEST, 500, NULL); 
			} 
		} 
 
		SetTransparent(m_hWnd, 0, m_nFade , LWA_ALPHA ); 
		break; 
	 
	case TIMER_PTTEST: 
	 
		::GetCursorPos(&m_point); 
		if (!m_rcRect.PtInRect(m_point)) 
		{ 
			KillTimer(TIMER_DELAY); 
			KillTimer(TIMER_PTTEST); 
			m_dwState = TIPS_FADEIN; 
			SetTimer(TIMER_FADE, 30, NULL); 
		} 
		break; 
		 
	default: 
		break; 
	} 
	CWnd::OnTimer(nIDEvent); 
} 
 
void CCoolTipCtrl::OnPaint()  
{ 
	CRect rect; 
	GetClientRect(&rect); 
	CPaintDC dc(this); 
 
	CFont font, *oldfont; 
	font.CreateFont(-12, 0, 0, 400, 600, 0, 0, 0, 0, 0, 0, 0, 1, "ËÎÌå"); 
	oldfont = dc.SelectObject(&font); 
	dc.SetBkMode(TRANSPARENT); 
 
	//Draw background ---------------------------------- 
	dc.FillSolidRect(rect, m_crBk); 
	dc.Draw3dRect(rect, RGB(140, 140, 140), RGB(99, 99, 99)); 
	 
	rect.InflateRect(-5, -5); 
	 
	//Draw title---------------------------------------- 
	if (m_hIcon != NULL) 
	{ 
		::DrawIconEx(dc.m_hDC, rect.left, rect.top, m_hIcon, 
				m_szIcon.cx, m_szIcon.cy, NULL, NULL, DI_NORMAL); 
		rect.left += m_szIcon.cx + 5; 
	} 
 
	if (m_strTitle != "") 
	{ 
		dc.SetTextColor(m_crTitle); 
		dc.DrawText(m_strTitle, rect, DT_LEFT | DT_SINGLELINE); 
		rect.top += 15; 
	} 
	 
	font.DeleteObject(); 
	font.CreateFont(-12, 0, 0, 400, 400, 0, 0, 0, 0, 0, 0, 0, 1, "ËÎÌå"); 
	dc.SelectObject(&font); 
	 
	//Draw text------------------------------------ 
	dc.SetTextColor(m_crText); 
	dc.DrawText(m_strText, rect, DT_LEFT | DT_WORDBREAK); 
	 
	dc.SelectObject(oldfont); 
	font.DeleteObject(); 
} 
 
/*=============================================================== 
	Set Transparent  
=================================================================*/ 
BOOL CCoolTipCtrl::SetTransparent(HWND hWnd, COLORREF crKey, BYTE bAlpha, DWORD dwFlags) 
{ 
	BOOL	bRet = FALSE; 
	typedef BOOL (WINAPI* lpfnSetTransparent)(HWND hWnd, COLORREF crKey, BYTE bAlpha, DWORD dwFlags); 
	 
	// Check that "USER32.dll" library has been loaded successfully... 
	if ( hUserDll ) 
	{ 
		lpfnSetTransparent pFnSetTransparent  = NULL; 
		pFnSetTransparent  = (lpfnSetTransparent)GetProcAddress(hUserDll, "SetLayeredWindowAttributes"); 
		if (pFnSetTransparent ) 
		{ 
			bRet = pFnSetTransparent(hWnd, crKey, bAlpha, dwFlags); 
		} 
	} //if( hUserDll ) 
 
	return bRet; 
} // End of SetTransparent function 
 
/*################################################################ 
				-------------------------------------- 
					CoolTip control display handlers 
				-------------------------------------- 
  ################################################################*/ 
 
void CCoolTipCtrl::SetRect(const CRect& rect) 
{ 
	m_rcRect = rect; 
} 
 
void CCoolTipCtrl::SetDelayTime(int nTime) 
{ 
	m_nDelayTime = nTime; 
} 
 
/*=============================================================== 
	display window 
=================================================================*/ 
BOOL CCoolTipCtrl::Show(CPoint point) 
{ 
	if (IsShow() && GetState() != TIPS_DELAYSHOW)  
	{ 
		if (m_dwState != TIPS_FADEIN) Hide(); 
		m_nFade = 10; 
		m_dwStyle |= TIPS_SHOWNEXT; 
		return FALSE; 
	} 
	m_point		= point; 
	m_nShowTime = m_nDelayTime; 
	m_dwState	= TIPS_DELAYSHOW; 
	SetTimer(TIMER_DELAY , 100, NULL); 
	SetTimer(TIMER_PTTEST, 500, NULL); 
	return TRUE;	 
} 
 
/*=============================================================== 
	hide window 
=================================================================*/ 
BOOL CCoolTipCtrl::Hide() 
{ 
	if (m_dwState == TIPS_HIDE) 
	{ 
		return FALSE; 
	} 
	m_dwState = TIPS_FADEIN; 
	SetTimer(TIMER_FADE, 30, NULL); 
	return TRUE; 
} 
 
BOOL CCoolTipCtrl::IsShow() 
{ 
	return (m_dwState != TIPS_HIDE) ; 
} 
 
void CCoolTipCtrl::DrawShadow(CDC *pDC, CRect rect, COLORREF color) 
{ 
	//Draw shadow----------------------------------------->> 
	COLORREF oldcolor = RGB(255, 255, 255); 
	BYTE newPixeValR, newPixeValG, newPixeValB; 
	BYTE AlphaArray[6] = {140, 170, 212, 240}; 
	BYTE AlphaArray2[] = {170, 205, 220, 240, 240, 250, 255}; 
	BYTE Alpha = 0; 
	 
	//bottom shadow----------------------------------------- 
	int i, j; 
	for (j = 0; j < 4; j++) 
	{ 
		Alpha = AlphaArray[j]; 
		for (i = 6; i <= rect.right - 5; i++) 
		{ 
			oldcolor = pDC->GetPixel(i, rect.bottom - (4 - j)); 
		 
			newPixeValR = GetRValue(oldcolor) * Alpha / 255;   
			newPixeValG = GetGValue(oldcolor) * Alpha / 255;   
			newPixeValB = GetBValue(oldcolor) * Alpha / 255;   
 
			pDC->SetPixel(i, rect.bottom - (4 - j), RGB(newPixeValR, newPixeValG, newPixeValB)); 
		} 
	} 
	 
	//right shadow----------------------------------------- 
	Alpha = 120; 
	for (i = 0; i < 4; i++) 
	{ 
		Alpha = AlphaArray[i]; 
		for (j = 6; j <= rect.bottom - 5; j++) 
		{ 
			oldcolor = pDC->GetPixel(rect.right - (4 - i), j); 
		 
			newPixeValR = GetRValue(oldcolor) * Alpha / 255;   
			newPixeValG = GetGValue(oldcolor) * Alpha / 255;   
			newPixeValB = GetBValue(oldcolor) * Alpha / 255;   
 
			pDC->SetPixel(rect.right - (4 - i), j, RGB(newPixeValR, newPixeValG, newPixeValB)); 
		} 
	} 
	 
	//other------------------------------------------------ 
	for (i = 0; i < 4; i++) 
	{ 
		for (j = 0; j < 4; j++) 
		{ 
			if ((i + j) > 6) break; 
			Alpha = AlphaArray2[j + i]; 
 
			oldcolor	= pDC->GetPixel(rect.right - 4 + i, rect.bottom - 4 + j); 
			newPixeValR = GetRValue(oldcolor) * Alpha / 255;   
			newPixeValG = GetGValue(oldcolor) * Alpha / 255;   
			newPixeValB = GetBValue(oldcolor) * Alpha / 255;   
			pDC->SetPixel(rect.right - 4 + i, rect.bottom - 4 + j, RGB(newPixeValR, newPixeValG, newPixeValB)); 
 
			oldcolor	= pDC->GetPixel(rect.right - 4 + i, rect.top + 5 - j); 
			newPixeValR = GetRValue(oldcolor) * Alpha / 255;   
			newPixeValG = GetGValue(oldcolor) * Alpha / 255;   
			newPixeValB = GetBValue(oldcolor) * Alpha / 255;   
			pDC->SetPixel(rect.right - 4 + i, rect.top + 5 - j, RGB(newPixeValR, newPixeValG, newPixeValB)); 
		 
			oldcolor	= pDC->GetPixel(rect.left - i + 5, rect.bottom - 4 + j); 
			newPixeValR = GetRValue(oldcolor) * Alpha / 255;   
			newPixeValG = GetGValue(oldcolor) * Alpha / 255;   
			newPixeValB = GetBValue(oldcolor) * Alpha / 255;   
			pDC->SetPixel(rect.left - i + 5, rect.bottom - 4 + j, RGB(newPixeValR, newPixeValG, newPixeValB)); 
		} 
	} 
} 
 
void CCoolTipCtrl::OnDraw(CDC *pDC) 
{ 
 
} 
 
/*################################################################ 
				------------------------------------ 
					CoolTip control size handlers 
				------------------------------------ 
  ################################################################*/ 
 
void CCoolTipCtrl::SetSize(CSize size) 
{ 
	m_nSize  = size; 
	CDC *pdc = GetDC(); 
	bitmap.DeleteObject(); 
	bitmap.CreateCompatibleBitmap(pdc, m_nSize.cx, m_nSize.cy); 
	m_MemDC.SelectObject(&bitmap); 
	ReleaseDC(pdc); 
} 
 
void CCoolTipCtrl::AutoSize() 
{ 
	int nstrLength = m_strTitle.GetLength(); 
	nstrLength = nstrLength > 30 ? nstrLength : 30; 
 
 	CSize szText = GetStringSize(m_strText, nstrLength, CSize(6, 12)); 
	m_nSize   = szText; 
	m_nSize.cx += 14; 
	m_nSize.cy += 14; 
	 
	if (m_strTitle != "" ) 
	{ 
		if (szText.cx < 180 && szText.cx < m_strTitle.GetLength() * 7 ) m_nSize.cx += m_strTitle.GetLength() * 7; 
		if (m_nSize.cx > 194) m_nSize.cx = 194; 
		m_nSize.cy += 15;		 
	} 
 
	m_nSize.cx += m_szIcon.cx + 5; 
	if (m_nSize.cy < m_szIcon.cy + 14 ) m_nSize.cy = m_szIcon.cy + 14; 
	SetSize(m_nSize); 
} 
 
CSize CCoolTipCtrl::GetStringSize(CString strText, int nlinecount, CSize szFont) 
{ 
	int npos = 0; 
	CSize sz(0,0); 
 
	while (true) 
	{ 
		npos = strText.Find('\n'); 
		if (npos >= 0) 
		{ 
			if  (npos > nlinecount) 
			{ 
				sz.cx = nlinecount; 
				sz.cy += npos / nlinecount + 1; 
			} 
			else 
			{ 
				sz.cx = sz.cx > npos ? sz.cx : npos; 
				sz.cy += 1; 
			} 
 
			if (npos < (strText.GetLength() - 1)) 
			{ 
				strText = strText.Right(strText.GetLength() - npos - 1); 
				continue; 
			} 
		} 
		else if (npos == -1) 
		{ 
			if  (strText.GetLength() > nlinecount) 
			{ 
				sz.cx = nlinecount; 
				sz.cy += strText.GetLength() / nlinecount + 1; 
			} 
			else 
			{ 
				sz.cx = sz.cx > strText.GetLength() ? sz.cx : strText.GetLength(); 
				sz.cy += 1; 
			} 
		} 
		break; 
	} 
	sz.cx = sz.cx * szFont.cx; 
	sz.cy = sz.cy * szFont.cy; 
	return sz; 
} 
 
/*################################################################ 
				------------------------------------ 
					CoolTip control text handlers 
				------------------------------------ 
  ################################################################*/ 
 
void CCoolTipCtrl::SetText(CString strText) 
{ 
	m_strText = strText; 
} 
 
void CCoolTipCtrl::SetTitle(CString strTitle) 
{ 
	m_strTitle = strTitle; 
} 
 
 
/*################################################################ 
				------------------------------------- 
					CoolTip control color handlers 
				------------------------------------- 
  ################################################################*/ 
 
void CCoolTipCtrl::SetTextColor(COLORREF crText) 
{ 
	m_crText = crText; 
} 
 
void CCoolTipCtrl::SetBkColor(COLORREF crBk) 
{ 
	m_crBk = crBk; 
} 
 
void CCoolTipCtrl::SetTitleColor(COLORREF crTitle) 
{ 
	m_crTitle = crTitle; 
} 
 
/*################################################################ 
				------------------------------------ 
					CoolTip control icon handlers 
				------------------------------------ 
  ################################################################*/ 
 
void CCoolTipCtrl::SetIcon(HICON hIcon, CSize szIcon) 
{ 
	m_hIcon = hIcon; 
	m_szIcon	 = szIcon; 
} 
 
 
 
void CCoolTipCtrl::OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS *lpncsp) 
{ 
	CRect rect = lpncsp->rgrc[0]; 
	rect.DeflateRect(0, 0, 4, 4); 
	lpncsp->rgrc[0] = rect; 
} 
 
void CCoolTipCtrl::OnNcPaint() 
{ 
	CWindowDC dc(this); 
	CRect rect; 
	GetWindowRect(&rect); 
	ScreenToClient(&rect); 
	dc.ExcludeClipRect(&CRect(0, 0, m_nSize.cx-4, m_nSize.cy-4)); 
	dc.BitBlt(0, 0, m_nSize.cx, m_nSize.cy, &m_MemDC, 0, 0, SRCCOPY); 
	DrawShadow(&dc, rect); 
} 
 
UINT CCoolTipCtrl::OnNcHitTest(CPoint point) 
{ 
	return HTCAPTION ; 
}