// Static.cpp : Implementation of cStatic #include "stdafx.h" #include "DecalControls.h" #include "Static.h" ///////////////////////////////////////////////////////////////////////////// // cStatic STDMETHODIMP cStatic::get_Font(IFontCacheDisp **pVal) { _ASSERTE( pVal != NULL ); if( m_pFont.p == NULL ) *pVal = NULL; else m_pFont->QueryInterface( pVal ); return S_OK; } STDMETHODIMP cStatic::putref_Font(IFontCacheDisp *newVal) { _ASSERTE( newVal != NULL ); if( m_pFont.p ) m_pFont.Release(); HRESULT hRes = newVal->QueryInterface( &m_pFont ); _ASSERTE( SUCCEEDED( hRes ) ); m_pSite->Invalidate(); return S_OK; } STDMETHODIMP cStatic::get_Text(BSTR *pVal) { _ASSERTE( pVal != NULL ); *pVal = OLE2BSTR( m_strText ); return S_OK; } STDMETHODIMP cStatic::put_Text(BSTR newVal) { _ASSERTE( newVal != NULL ); m_strText = newVal; m_pSite->Invalidate(); return S_OK; } STDMETHODIMP cStatic::SchemaLoad(IView *pView, IUnknown *pSchema) { CComPtr< IPluginSite > pPlugin; m_pSite->get_PluginSite( &pPlugin ); pPlugin->CreateFontSchema( 14, 0, pSchema, &m_pFont ); MSXML::IXMLDOMElementPtr pElement = pSchema; _variant_t vText = pElement->getAttribute( _T( "text" ) ), vTextColor = pElement->getAttribute( _T( "textcolor" ) ), vWidth = pElement->getAttribute( _T( "width" ) ), vHeight = pElement->getAttribute( _T( "height" ) ), vJustify = pElement->getAttribute( _T( "justify" ) ), vOutline = pElement->getAttribute( _T( "outlinecolor" ) ), vAntialias = pElement->getAttribute( _T( "aa" ) ); // This is a required element _ASSERTE( vText.vt == VT_BSTR ); // Store the text, assume left justification m_strText = vText.bstrVal; m_eJustify = eFontLeft; // Determine the proper justification if (vJustify.vt != VT_NULL) { _bstr_t bstrJustify = vJustify.bstrVal; if (::_wcsicmp(L"left", bstrJustify) == 0) { m_eJustify = eFontLeft; } else if (::_wcsicmp(L"right", bstrJustify) == 0) { m_eJustify = eFontRight; } else if (::_wcsicmp(L"center", bstrJustify) == 0) { m_eJustify = eFontCenter; } } // Determine the color if( vTextColor.vt != VT_NULL ) { try { m_nTextColor = static_cast< long >( vTextColor ); } catch( ... ) { // Type conversion error _ASSERTE( FALSE ); } } m_nOutlineColor = 0; m_bOutline = false; if( vOutline.vt != VT_NULL ) { try { m_bOutline = true; m_nOutlineColor = static_cast< long >( vOutline ); } catch( ... ) { // Type conversion error _ASSERTE( FALSE ); } } m_bAA = true; if( vAntialias.vt != VT_NULL ) { try { m_bAA = static_cast< bool >( vAntialias ); } catch( ... ) { // Type conversion error _ASSERTE( FALSE ); } } /* // Set the width of the static (not same as text width) if( vWidth.vt != VT_NULL ) { try { m_nWidth = static_cast< long >( vWidth ); } catch( ... ) { // Type conversion error _ASSERTE( FALSE ); } } // Set the height of the static (not same as text height or fontsize) if( vHeight.vt != VT_NULL ) { try { m_nHeight = static_cast< long >( vHeight ); } catch( ... ) { // Type conversion error _ASSERTE( FALSE ); } } */ return S_OK; } STDMETHODIMP cStatic::Render( ICanvas *pCanvas ) { if( m_pFont.p == NULL ) { // Create the default font CComPtr< IPluginSite > pPlugin; m_pSite->get_PluginSite( &pPlugin ); BSTR bstrFontName; pPlugin->get_FontName(&bstrFontName); pPlugin->CreateFont( bstrFontName /*_bstr_t( _T( "Times New Roman" ) )*/, 14, 0, &m_pFont ); } SIZE Size; char *token; POINT ptText = { 0, 0 }; //_bstr_t strText= m_strText.copy(); //_bstr_t temp=_bstr_t(""); // Determine control size RECT rcPos; m_pSite->get_Position(&rcPos); int nWidth = rcPos.right - rcPos.left; int nHeight = rcPos.bottom - rcPos.top; // Copy the string for parsing std::string strText((const char *) m_strText); // Determine line height m_pFont->MeasureText(_bstr_t(strText.data()), &Size); int height = Size.cy; // Break it into lines (can't use strtok or we miss blank lines) std::vector<_bstr_t> lines; int nStart = 0, nEnd; bool bDone = false; while (!bDone) { // Get the next CR nEnd = strText.find("\n", nStart); if (nEnd == std::string::npos) { bDone = true; nEnd = strText.length(); } // Store the line lines.push_back(strText.substr(nStart, nEnd - nStart).data()); // Move one character beyond nStart = nEnd + 1; } // Loop through the lines _bstr_t bstrSpace(" "), bstrEmpty(""); int nIndex, nLines = lines.size(); for (nIndex = 0, bDone = false; !bDone && (nIndex < nLines); nIndex++) { // Copy the line for parsing _bstr_t strLine((const char *) lines[nIndex]); // Line to be built _bstr_t strOut = bstrEmpty; // Loop through the "words" on the line for (token = ::strtok((char *) strLine, " "); !bDone && (token != NULL); token = ::strtok(NULL, " ")) { _bstr_t bstrToken(token); // Measure this token m_pFont->MeasureText(strOut + bstrToken, &Size); // Is this line full??? if (Size.cx > nWidth) { DrawText(&ptText, strOut, pCanvas); ptText.y += height; // Does the next line put us over the top bDone = ((ptText.y + height) > nHeight) ? true : false; // Clear the line strOut = bstrEmpty; } // Store the token strOut += bstrToken + bstrSpace; } // Draw as needed if (!bDone) { DrawText(&ptText, strOut, pCanvas); ptText.y += height; } // Does the next line put us over the top bDone = ((ptText.y + height) > nHeight) ? true : false; } /* if(Size.cx > nWidth) { for( token = ::strtok( (char*)strText, " " ); token !=NULL; token = ::strtok( NULL, " " ) ) { m_pFont->MeasureText(temp + _bstr_t(token), &Size); if(Size.cx > nWidth) { DrawText( &ptText, temp, pCanvas ); ptText.y+=height;//14; if(ptText.y+height>nHeight) return S_OK; temp = _bstr_t(token) + _bstr_t(" "); } else temp += _bstr_t(token) + _bstr_t(" "); } DrawText( &ptText, temp, pCanvas ); } else { DrawText( &ptText, strText, pCanvas ); } */ return S_OK; } STDMETHODIMP cStatic::get_TextColor(long *pVal) { _ASSERTE( pVal != NULL ); *pVal = m_nTextColor; return S_OK; } STDMETHODIMP cStatic::put_TextColor(long newVal) { _ASSERTE( ( newVal & 0xFF000000L ) == 0 ); m_nTextColor = newVal; m_pSite->Invalidate(); return S_OK; } void cStatic::DrawText(LPPOINT ppt, BSTR szText, ICanvas *pCanvas) { POINT pt = *ppt; RECT rcPos; m_pSite->get_Position(&rcPos); int nWidth = rcPos.right - rcPos.left; int nHeight = rcPos.bottom - rcPos.top; // Act based on justification style switch (m_eJustify) { case eFontRight: { SIZE Size; m_pFont->MeasureText(szText, &Size); pt.x = nWidth - Size.cx; } break; case eFontCenter: { SIZE Size; m_pFont->MeasureText(szText, &Size); pt.x = (nWidth / 2) - (Size.cx / 2); } break; case eFontLeft: default: { // No-Op } break; } long lFlags = 0; if( m_bAA ) lFlags |= eAA; if( m_bOutline ) lFlags |= eOutlined; m_pFont->DrawTextEx( &pt, szText, m_nTextColor, m_nOutlineColor, lFlags, pCanvas ); }