LONG FAR PASCAL SubClassFunc( HWND hwnd, WORD msg, WORD wParam, LONG lParam )
{
	switch( msg )
	{
		case WM_CREATE:
			{
				Property *pProp = new Property;
				pProp->m_defaults.m_rcMargins.Set( 2, 2, 5, 5 );
				SetProp( hwnd, g_pcszProperty, reinterpret_cast<HANDLE>( pProp ) );
			}
			break;


		case WM_DESTROY:
			{
				Property *pProp = reinterpret_cast<Property *>( RemoveProp( hwnd, g_pcszProperty ) );
				delete pProp;
			}
			break;

		case WM_WINDOWPOSCHANGING:
			{
				WINDOWPOS &pos = *(WINDOWPOS *)lParam;
				Property *pProp = reinterpret_cast<Property *>( GetProp( hwnd, g_pcszProperty ) );
				if( !(pos.flags & SWP_NOSIZE) && !( pos.flags & SWP_NOMOVE ) && pProp )
				{
					CWindowText text( hwnd );
					if( text.GetLength() )
					{
						HFONT hFont = (HFONT)SendMessage( hwnd, WM_GETFONT, 0, 0 );
						pProp->m_defaults.SetFont( hFont );
						pProp->m_sectHTML.SetHTML( text, text.GetLength(), NULL );
					}
					return 0;
				}
			}
		break;

		case WM_WINDOWPOSCHANGED:
		{
			static bool bDealingWithIt = false;
			Property *pProp = reinterpret_cast<Property *>( GetProp( hwnd, g_pcszProperty ) );
			if( pProp && !bDealingWithIt )
			{
				bDealingWithIt = true;

				CRect rcTip( 0, 0, 300, 5 );
				CDrawContext dc;
				pProp->m_sectHTML.OnLayout( rcTip, dc );
				const CSize size( pProp->m_sectHTML.GetSize() );
				rcTip.SetSize( size );
				pProp->m_sectHTML.bottom = size.cy;
				pProp->m_sectHTML.right = size.cx;

				CPoint ptCursor;
				GetCursorPos( ptCursor );
				ptCursor.x += g_knTipClearanceX;
				ptCursor.y += g_knTipClearanceY;
				rcTip.Offset( ptCursor.x, ptCursor.y );

				CRect rcDesktop;
				GetDisplayWorkArea( hwnd, rcDesktop );
				if( rcTip.right >= rcDesktop.right )
				{
					rcTip.Offset( -(rcTip.right - rcDesktop.right) - g_knTipClearanceX, 0 );
				}

				if( rcTip.bottom >= rcDesktop.bottom )
				{
					rcTip.Offset( 0, -rcTip.Height() - g_knTipClearanceY );
				}
				SetWindowPos( hwnd, NULL, rcTip.left, rcTip.top, rcTip.Width(), rcTip.Height(), SWP_NOACTIVATE | SWP_NOSENDCHANGING | SWP_NOZORDER );
				bDealingWithIt = false;
			}
			return 0;
		}

		case WM_PAINT:
		{
			Property *pProp = reinterpret_cast<Property *>( GetProp( hwnd, g_pcszProperty ) );
			if( pProp )
			{
				PAINTSTRUCT ps;
				BeginPaint( hwnd, &ps );

				CRect rcPaint( ps.rcPaint );
				if( rcPaint.IsEmpty() )
				{
					GetClientRect( hwnd, &rcPaint );
				}
				//
				//	Scoped to allow the draw context to go out of scope before EndPaint is called.
				{
					CDrawContext dc( &rcPaint, ps.hdc );
					SelectPalette( ps.hdc, GetCurrentWindowsPalette(), TRUE );
					RealizePalette( ps.hdc );
					pProp->m_sectHTML.OnDraw( dc );
				}
				EndPaint( hwnd, &ps );
				return 0;
			}
			break;
		}
	}

	return CallWindowProc( g_lpfnOldWndProc, hwnd, msg, wParam, lParam);
}
Exemple #2
0
CTipWindow::CTipWindow( LPCTSTR pcszTip, CPoint &pt )
    :	CWindowSection( TIP_WINDOW )
    , m_defaults( g_defaults )
    , m_htmlSection( this, &m_defaults )
{
    NONCLIENTMETRICS ncm;
    ncm.cbSize = sizeof( ncm );
    if( SystemParametersInfo( SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &ncm, 0 ) )
    {
        m_defaults.SetFont( ncm.lfStatusFont );
    }
    ASSERT( pcszTip );
    m_strTip = pcszTip;

    CRect rcDesktop;
    GetDisplayWorkArea( pt, rcDesktop );
    m_htmlSection.SetZoomLevel( QHTM_ZOOM_DEFAULT );

    //
    //	Stop tip exceeding 'g_knMaxHeight' pixels
    bool bDeleted = false;
    while( HeightExceedsTipMax( m_strTip, g_knMaxHeight ) )
    {
        int iDeleteAt = m_strTip.GetLength() - m_strTip.GetLength() / 100 * 15; // Knock 15% off
        m_strTip.Delete( iDeleteAt, m_strTip.GetLength() - iDeleteAt );

        UINT iCheckHTML = m_strTip.GetLength() - 1;
        while( iCheckHTML + 5 > m_strTip.GetLength() )
        {
            if( m_strTip[iCheckHTML] == '<' )
            {
                m_strTip.Delete( iCheckHTML, m_strTip.GetLength() - iCheckHTML );
                break;
            }
            iCheckHTML--;
        }
        bDeleted = true;
    }

    if( bDeleted )
    {
        m_strTip += _T("...<br><b>more</b>");
    }

    m_defaults.m_crBackground = GetSysColor( COLOR_INFOBK );
    m_defaults.m_crDefaultForeColour = GetSysColor( COLOR_INFOTEXT );

    m_htmlSection.SetHTML( m_strTip, m_strTip.GetLength(), NULL );
    CRect rcMargins( 2, 2, 2, 5 );
    m_htmlSection.SetDefaultMargins( rcMargins );
    CRect rcTip( 0, 0, g_knMaxTipWidth, 30 );
    CDrawContext dc;
    m_htmlSection.OnLayout( rcTip, dc );
    const CSize size( m_htmlSection.GetSize() );

    //
    //	Adjust for mouse size
    pt.x += g_knTipClearanceX;
    pt.y += g_knTipClearanceY;

    rcTip.Set( pt.x, pt.y , pt.x + size.cx + 3, pt.y + size.cy );

    //
    //	Move rect around based on desktop rect
    if( rcTip.right > rcDesktop.right )
    {
        rcTip.Offset( -(rcTip.right - rcDesktop.right - g_knTipClearanceX), 0 );
    }

    if( rcTip.bottom > rcDesktop.bottom )
    {
        rcTip.Offset( 0, -rcTip.Height() - g_knTipClearanceY );
    }


    //
    //	Adjust tip so that it is within bounds
    VERIFY( CWindowSection::Create( rcTip ) );
    m_nLastTipCreated = GetTickCount();
    ShowWindow( SW_SHOW );
}