www.pudn.com > vistaListCtrlDemo.zip > TitleTip.h


 
#pragma once 
 
#include  
 
class CTitleTip : public CWindowImpl< CTitleTip > 
{ 
public: 
	CTitleTip() 
	{ 
		m_hWndParent = NULL; 
		m_bShowThemed = TRUE; 
	} 
	 
	~CTitleTip() 
	{ 
	} 
	 
	DECLARE_WND_CLASS_EX( _T( "TitleTip" ), CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS | CS_SAVEBITS, COLOR_WINDOW ) 
 
protected: 
	HWND m_hWndParent; 
	BOOL m_bShowThemed; 
	CString m_strToolTip; 
	 
	COLORREF m_rgbBackground; 
	COLORREF m_rgbTextColour; 
	COLORREF m_rgbBorderOuter; 
	COLORREF m_rgbBorderInner; 
	COLORREF m_rgbBackgroundTop; 
	COLORREF m_rgbBackgroundBottom; 
	 
	CFont m_fntTitleFont; 
	CToolTipCtrl m_ttToolTip; 
	 
public: 
	BOOL Create( HWND hWndParent, BOOL bShowThemed ) 
	{ 
		m_hWndParent = hWndParent; 
		m_bShowThemed = bShowThemed; 
		 
		m_rgbBackground = GetSysColor( COLOR_INFOBK ); 
		m_rgbTextColour = ( m_bShowThemed && CTheme::IsThemingSupported() ) ? GetSysColor( COLOR_WINDOWTEXT ) : GetSysColor( COLOR_INFOTEXT );		 
		m_rgbBorderOuter = RGB( 220, 220, 220 ); 
		m_rgbBorderInner = RGB( 245, 245, 245 ); 
		m_rgbBackgroundTop = RGB( 250, 250, 250 ); 
		m_rgbBackgroundBottom = RGB( 235, 235, 235 ); 
		 
		if ( CWindowImpl< CTitleTip >::Create( hWndParent, NULL, NULL, WS_POPUP, WS_EX_TOOLWINDOW | WS_EX_TOPMOST ) == NULL ) 
			return FALSE; 
		 
		// create the tooltip 
		if ( !m_ttToolTip.Create( m_hWnd ) ) 
			return FALSE; 
		m_ttToolTip.SetMaxTipWidth( SHRT_MAX ); 
		 
		// get system message font 
		CLogFont logFont; 
		logFont.SetMessageBoxFont(); 
		if ( !m_fntTitleFont.IsNull() ) 
			m_fntTitleFont.DeleteObject(); 
		return ( m_fntTitleFont.CreateFontIndirect( &logFont ) != NULL ); 
	} 
	 
	BOOL Show( CRect& rcRect, LPCTSTR lpszItemText, LPCTSTR lpszToolTip ) 
	{ 
		CString strItemText = lpszItemText; 
		 
		if ( !IsWindow() || strItemText.IsEmpty() ) 
			return FALSE; 
		 
		m_strToolTip = lpszToolTip; 
		SetWindowText( strItemText ); 
		 
		CClientDC dcClient( m_hWnd ); 
		 
		HFONT hOldFont = dcClient.SelectFont( m_fntTitleFont ); 
			 
		CRect rcTextExtent( rcRect ); 
				 
		// calculate item text extent... 
		dcClient.DrawText( strItemText, strItemText.GetLength(), rcTextExtent, DT_LEFT | DT_SINGLELINE | DT_NOPREFIX | DT_VCENTER | DT_CALCRECT ); 
		 
		dcClient.SelectFont( hOldFont ); 
		 
		// do not show titletip if entire text is visible 
		if ( rcTextExtent.Width() <= rcRect.Width() - 1 ) 
			return FALSE; 
		 
		if ( m_strToolTip.IsEmpty() ) 
			m_ttToolTip.Activate( FALSE ); 
		else 
		{ 
			m_ttToolTip.Activate( TRUE ); 
			m_ttToolTip.AddTool( m_hWnd, (LPCTSTR)m_strToolTip.Left( SHRT_MAX ) ); 
		} 
		 
		// show titletip at new location 
		if ( !SetWindowPos( NULL, rcRect.left - 4, rcRect.top, rcTextExtent.Width() + 11, rcRect.Height(), SWP_NOZORDER | SWP_SHOWWINDOW | SWP_NOACTIVATE | SWP_NOCOPYBITS ) ) 
			return FALSE; 
		 
		SetCapture(); 
		 
		return TRUE; 
	} 
	 
	BOOL Hide() 
	{ 
		if ( GetCapture() == m_hWnd ) 
			ReleaseCapture(); 
		return IsWindow() ? ShowWindow( SW_HIDE ) : FALSE; 
	} 
	 
	BEGIN_MSG_MAP_EX(CTitleTip) 
		MSG_WM_DESTROY(OnDestroy) 
		MESSAGE_RANGE_HANDLER_EX(WM_MOUSEFIRST,WM_MOUSELAST,OnMouseRange) 
		MSG_WM_ERASEBKGND(OnEraseBkgnd) 
		MSG_WM_PAINT(OnPaint) 
	END_MSG_MAP_EX() 
	 
	void OnDestroy() 
	{ 
		if ( m_ttToolTip.IsWindow() ) 
			m_ttToolTip.DestroyWindow(); 
		m_ttToolTip.m_hWnd = NULL; 
	} 
	 
	LRESULT OnMouseRange( UINT nMessage, WPARAM wParam, LPARAM lParam ) 
	{ 
		SetMsgHandled( FALSE ); 
		 
		if ( m_ttToolTip.IsWindow() ) 
		{ 
			MSG msgRelay = { m_hWnd, nMessage, wParam, lParam }; 
			m_ttToolTip.RelayEvent( &msgRelay ); 
		} 
		 
		CPoint ptMouse( GET_X_LPARAM( lParam ), GET_Y_LPARAM( lParam ) ); 
		ClientToScreen( &ptMouse ); 
		 
		if ( nMessage == WM_MOUSEMOVE ) 
		{ 
			CRect rcWindow; 
			GetWindowRect( rcWindow );		 
			if ( !rcWindow.PtInRect( ptMouse ) ) 
				Hide(); 
			return 0; 
		}		 
										 
		CWindow wndParent( m_hWndParent ); 
		UINT nHitTest = wndParent.SendMessage( WM_NCHITTEST, 0, MAKELPARAM( ptMouse.x, ptMouse.y ) ); 
		 
		// forward notifcation through to parent 
		if ( nHitTest == HTCLIENT ) 
		{ 
			wndParent.ScreenToClient( &ptMouse ); 
			wndParent.PostMessage( nMessage, wParam, MAKELPARAM( ptMouse.x, ptMouse.y ) ); 
		} 
		else 
		{ 
			switch ( nMessage ) 
			{ 
				case WM_LBUTTONDOWN:	wndParent.PostMessage( WM_NCLBUTTONDOWN, nHitTest, MAKELPARAM( ptMouse.x, ptMouse.y ) ); 
										break; 
				case WM_LBUTTONUP:		wndParent.PostMessage( WM_NCLBUTTONUP, nHitTest, MAKELPARAM( ptMouse.x, ptMouse.y ) ); 
										break; 
				case WM_LBUTTONDBLCLK:	wndParent.PostMessage( WM_NCLBUTTONDBLCLK, nHitTest, MAKELPARAM( ptMouse.x, ptMouse.y ) ); 
										break; 
				case WM_RBUTTONDOWN:	wndParent.PostMessage( WM_NCRBUTTONDOWN, nHitTest, MAKELPARAM( ptMouse.x, ptMouse.y ) ); 
										break; 
				case WM_RBUTTONUP:		wndParent.PostMessage( WM_NCRBUTTONUP, nHitTest, MAKELPARAM( ptMouse.x, ptMouse.y ) ); 
										break; 
				case WM_RBUTTONDBLCLK:	wndParent.PostMessage( WM_NCRBUTTONDBLCLK, nHitTest, MAKELPARAM( ptMouse.x, ptMouse.y ) ); 
										break; 
				case WM_MBUTTONDOWN:	wndParent.PostMessage( WM_NCMBUTTONDOWN, nHitTest, MAKELPARAM( ptMouse.x, ptMouse.y ) ); 
										break; 
				case WM_MBUTTONUP:		wndParent.PostMessage( WM_NCMBUTTONUP, nHitTest, MAKELPARAM( ptMouse.x, ptMouse.y ) ); 
										break; 
				case WM_MBUTTONDBLCLK:	wndParent.PostMessage( WM_NCMBUTTONDBLCLK, nHitTest, MAKELPARAM( ptMouse.x, ptMouse.y ) ); 
										break; 
			} 
		} 
 
		return 0; 
	} 
	 
	BOOL OnEraseBkgnd( HDC dc )  
	{ 
		return TRUE; 
	} 
	 
	void OnPaint( HDC ) 
	{ 
		CPaintDC dcPaint( m_hWnd ); 
		 
		int nContextState = dcPaint.SaveDC(); 
		 
		CRect rcClient; 
		GetClientRect( rcClient ); 
		 
		CRect rcTitleTip( rcClient ); 
					 
		if ( m_bShowThemed && CTheme::IsThemingSupported() ) 
		{ 
			CPen penBorder; 
			penBorder.CreatePen( PS_SOLID, 1, m_rgbBorderOuter ); 
			 
			dcPaint.SelectPen( penBorder ); 
			dcPaint.SelectStockBrush( HOLLOW_BRUSH ); 
			 
			dcPaint.RoundRect( rcTitleTip, CPoint( 5, 5 ) ); 
			rcTitleTip.DeflateRect( 1, 1 ); 
			 
			CPen penInnerBorder; 
			penInnerBorder.CreatePen( PS_SOLID, 1, m_rgbBorderInner ); 
			dcPaint.SelectPen( penInnerBorder ); 
			 
			dcPaint.RoundRect( rcTitleTip, CPoint( 2, 2 ) ); 
			rcTitleTip.DeflateRect( 1, 1 ); 
			 
			GRADIENT_RECT grdRect = { 0, 1 }; 
			TRIVERTEX triVertext[ 2 ] = { 
											rcTitleTip.left, 
											rcTitleTip.top, 
											GetRValue( m_rgbBackgroundTop ) << 8, 
											GetGValue( m_rgbBackgroundTop ) << 8, 
											GetBValue( m_rgbBackgroundTop ) << 8, 
											0x0000,			 
											rcTitleTip.right, 
											rcTitleTip.bottom, 
											GetRValue( m_rgbBackgroundBottom ) << 8, 
											GetGValue( m_rgbBackgroundBottom ) << 8, 
											GetBValue( m_rgbBackgroundBottom ) << 8, 
											0x0000 
										}; 
			 
			dcPaint.GradientFill( triVertext, 2, &grdRect, 1, GRADIENT_FILL_RECT_V ); 
		} 
		else 
		{ 
			dcPaint.SetBkColor( m_rgbBackground ); 
			dcPaint.ExtTextOut( rcTitleTip.left, rcTitleTip.top, ETO_OPAQUE, rcTitleTip, _T( "" ), 0, NULL ); 
			 
			CBrush bshTitleFrame; 
			bshTitleFrame.CreateSolidBrush( m_rgbTextColour ); 
			dcPaint.FrameRect( rcTitleTip, bshTitleFrame ); 
		} 
		 
		int nTextLength = GetWindowTextLength() + 1; 
		CString strItemText; 
		GetWindowText( strItemText.GetBuffer( nTextLength ), nTextLength ); 
		strItemText.ReleaseBuffer(); 
		 
		dcPaint.SelectFont( m_fntTitleFont ); 
		dcPaint.SetTextColor( m_rgbTextColour ); 
		dcPaint.SetBkMode( TRANSPARENT ); 
		 
		CRect rcItemText( rcClient ); 
		rcItemText.OffsetRect( 4, 0 ); 
		 
		dcPaint.DrawText( strItemText, strItemText.GetLength(), rcItemText, DT_LEFT | DT_SINGLELINE | DT_NOPREFIX | DT_VCENTER ); 
	 
		dcPaint.RestoreDC( nContextState ); 
	} 
};