// Checkbox.cpp : Implementation of cCheckbox #include "stdafx.h" #include "DecalControls.h" #include "Checkbox.h" ///////////////////////////////////////////////////////////////////////////// // cCheckbox cCheckbox::cCheckbox() : m_bChecked( VARIANT_FALSE ), m_bRightToLeft( VARIANT_FALSE ), m_nTextColor( RGB( 0, 0, 0 ) ), m_bPressed( VARIANT_FALSE ), m_bMouseIn( VARIANT_FALSE ) { } STDMETHODIMP cCheckbox::get_Font(IFontCacheDisp **pVal) { _ASSERTE( pVal != NULL ); if( m_pFont.p == NULL ) *pVal = NULL; else m_pFont->QueryInterface( pVal ); return S_OK; } STDMETHODIMP cCheckbox::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->Reformat(); return S_OK; } STDMETHODIMP cCheckbox::get_Text(BSTR *pVal) { _ASSERTE( pVal != NULL ); *pVal = OLE2BSTR( m_strText ); return S_OK; } STDMETHODIMP cCheckbox::put_Text(BSTR newVal) { _ASSERTE( newVal != NULL ); m_strText = newVal; m_pSite->Reformat(); return S_OK; } STDMETHODIMP cCheckbox::get_TextColor(long *pVal) { _ASSERTE( pVal != NULL ); *pVal = m_nTextColor; return S_OK; } STDMETHODIMP cCheckbox::put_TextColor(long newVal) { _ASSERTE( ( newVal & 0xFF000000L ) == 0 ); m_nTextColor = newVal; m_pSite->Invalidate(); return S_OK; } STDMETHODIMP cCheckbox::get_Checked(VARIANT_BOOL *pVal) { _ASSERTE( pVal != NULL ); *pVal = m_bChecked; return S_OK; } STDMETHODIMP cCheckbox::put_Checked(VARIANT_BOOL newVal) { if( m_bChecked == newVal ) return S_OK; m_bChecked = newVal; m_pSite->Invalidate(); return S_OK; } STDMETHODIMP cCheckbox::get_RightToLeft(VARIANT_BOOL *pVal) { _ASSERTE( pVal != NULL ); *pVal = m_bRightToLeft; return S_OK; } STDMETHODIMP cCheckbox::put_RightToLeft(VARIANT_BOOL newVal) { m_bRightToLeft = newVal; m_pSite->Reformat(); return S_OK; } STDMETHODIMP cCheckbox::SchemaLoad(IView *pView, IUnknown *pSchema) { // First attempt to load the font 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" ) ), vRightToLeft = pElement->getAttribute( _T( "righttoleft" ) ), vChecked = pElement->getAttribute( _T( "checked" ) ), vOutline = pElement->getAttribute( _T( "outlinecolor" ) ), vAntialias = pElement->getAttribute( _T( "aa" ) ); // Text must exist _ASSERTE( vText.vt == VT_BSTR ); m_strText = vText.bstrVal; if( vTextColor.vt != VT_NULL ) { try { m_nTextColor = static_cast< long >( vTextColor ); } catch( ... ) { // Type conversion error _ASSERTE( FALSE ); } } if( vRightToLeft.vt != VT_NULL ) { try { m_bRightToLeft = ( static_cast< bool >( vRightToLeft ) ) ? VARIANT_TRUE : VARIANT_FALSE; } catch( ... ) { // Type conversion error _ASSERTE( FALSE ); } } if( vChecked.vt != VT_NULL ) { try { m_bChecked = ( static_cast< bool >( vChecked ) ) ? VARIANT_TRUE : VARIANT_FALSE; } 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 ); } } return S_OK; } #define CHECK_SIZE 13 #define TEXT_OFFSET 4 STDMETHODIMP cCheckbox::Reformat() { if( m_pFont.p == NULL ) { // No font was specified, 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 ); } RECT rc; m_pSite->get_Position( &rc ); SIZE szText; m_pFont->MeasureText( m_strText, &szText ); if( szText.cy >= CHECK_SIZE ) { m_ptCheck.y = ( szText.cy - CHECK_SIZE ) / 2; m_ptText.y = 0; } else { m_ptCheck.y = 0; m_ptText.y = ( CHECK_SIZE - szText.cy ) / 2; } if( m_bRightToLeft ) { m_ptText.x = ( rc.right - rc.left ) - ( CHECK_SIZE + TEXT_OFFSET ) - szText.cx; m_ptCheck.x = ( rc.right - rc.left ) - CHECK_SIZE; } else { m_ptText.x = CHECK_SIZE + TEXT_OFFSET; m_ptCheck.x = 0; } return S_OK; } STDMETHODIMP cCheckbox::Render( ICanvas *pCanvas ) { bool bChecked = ( m_bPressed && m_bMouseIn ) ? !m_bChecked : !!m_bChecked; CComPtr< IPluginSite > pPlugin; m_pSite->get_PluginSite( &pPlugin ); CComPtr< IIconCache > pIcon; SIZE szIcon = { CHECK_SIZE, CHECK_SIZE }; pPlugin->GetIconCache( &szIcon, &pIcon ); pIcon->DrawIcon( &m_ptCheck, ( bChecked ) ? 0x0600128B : 0x0600128D, 0, pCanvas ); long lFlags = 0; if( m_bAA ) lFlags |= eAA; if( m_bOutline ) lFlags |= eOutlined; m_pFont->DrawTextEx( &m_ptText, m_strText, m_nTextColor, m_nOutlineColor, lFlags, pCanvas ); return S_OK; } STDMETHODIMP cCheckbox::MouseEnter(struct MouseState *) { _ASSERTE( !m_bMouseIn ); m_bMouseIn = VARIANT_TRUE; if( m_bPressed ) { _ASSERTE( m_pSite.p != NULL ); m_pSite->Invalidate(); } return S_OK; } STDMETHODIMP cCheckbox::MouseExit(struct MouseState *) { _ASSERTE( m_bMouseIn ); m_bMouseIn = VARIANT_FALSE; if( m_bPressed ) { _ASSERTE( m_pSite.p != NULL ); m_pSite->Invalidate(); } return S_OK; } STDMETHODIMP cCheckbox::MouseDown(struct MouseState *) { _ASSERTE( m_pSite != NULL ); m_bPressed = VARIANT_TRUE; m_pSite->Invalidate(); return S_OK; } STDMETHODIMP cCheckbox::MouseUp(struct MouseState *) { m_bPressed = VARIANT_FALSE; long nID; m_pSite->get_ID( &nID ); if( m_bMouseIn ) { _ASSERTE( m_pSite.p != NULL ); m_bChecked = ( m_bChecked ) ? VARIANT_FALSE : VARIANT_TRUE; m_pSite->Invalidate(); // NOTE: The command may destroy the control synchronously // so we make a stack copy of the target in case our instance is destroyed // for the purpose of completing the command Fire_Change( nID, m_bChecked ); } return S_OK; }