// View.cpp : Implementation of cView #include "stdafx.h" #include "Inject.h" #include "View.h" #include "RootLayer.h" #include "Manager.h" #include "InjectApi.h" ///////////////////////////////////////////////////////////////////////////// // cView cView::~cView() { m_pRoot->m_pBars->RemoveBar( m_nViewID ); m_pRoot->m_pPanel->RemoveView( m_nViewID ); m_pRoot->removeView( this ); } void cView::loadSchema( BSTR strSchema, IUnknown **ppRootControl ) { USES_CONVERSION; _ASSERTE( strSchema != NULL ); // Create a new XML document and load this up MSXML::IXMLDOMDocumentPtr pDoc; pDoc.CreateInstance( __uuidof( MSXML::DOMDocument ), NULL, CLSCTX_INPROC_SERVER ); VARIANT_BOOL bSuccess; if( strSchema[ 0 ] == OLESTR( '<' ) ) bSuccess = pDoc->loadXML( strSchema ); else { // Load from a file source pDoc->async = VARIANT_FALSE; TCHAR szPath[ MAX_PATH ]; bSuccess = pDoc->load( ::InjectMapPath( eInjectPathAgent, OLE2T( strSchema ), szPath ) ); } if( !bSuccess ) { USES_CONVERSION; // The document failed to load, get the error info for posterity MSXML::IXMLDOMParseErrorPtr pErr = pDoc->parseError; long nCode = pErr->errorCode; long nFilePos = pErr->filepos; long nLine = pErr->line; long nLinePos = pErr->linepos; _bstr_t strReason = pErr->reason; _bstr_t strText = pErr->srcText; TCHAR szError[ 1024 ]; ::_stprintf( szError, _T( "0x%08X (%i, %i): %s" ), nCode, nLine, nLinePos, OLE2T( strReason ) ); ::MessageBox( cManager::_p->m_hMain, szError, _T( "XML Parse Error" ), MB_ICONERROR | MB_OK ); // Give the user a chance to break and look at this lovely info _ASSERTE( FALSE ); return; } // Get the root element and check it out loadSchemaObject( pDoc->documentElement, ppRootControl ); } void cView::loadSchemaObject( IUnknown *pObject, IUnknown **ppRootControl ) { MSXML::IXMLDOMElementPtr pRoot = pObject; _ASSERTE( pRoot->tagName == _bstr_t( _T( "view" ) ) ); // Get the view parameters _variant_t vIconModule = pRoot->getAttribute( _T( "iconlibrary" ) ), vIcon = pRoot->getAttribute( _T( "icon" ) ), vTitle = pRoot->getAttribute( _T( "title" ) ), vLeft = pRoot->getAttribute( _T( "left" ) ), vTop = pRoot->getAttribute( _T( "top" ) ), vWidth = pRoot->getAttribute( _T( "width" ) ), vHeight = pRoot->getAttribute( _T( "height" ) ); // We *must* have a title _ASSERTE( vTitle.vt == VT_BSTR ); // Fill this into a view param _ASSERTE( vIcon.vt != VT_NULL ); m_nIcon = ( vIcon.vt != VT_NULL ) ? static_cast< long >( vIcon ) + 0x06000000 : 0; if( vIconModule.vt == VT_BSTR ) cManager::_p->LoadResourceModule( vIconModule.bstrVal, &m_nIconModule ); else m_nIconModule = 0; if(vLeft.vt == VT_NULL) m_nLeft = 0; else m_nLeft = static_cast< long >(vLeft); if(vTop.vt == VT_NULL) m_nTop = 70; else m_nTop = static_cast< long >(vTop); if(vWidth.vt == VT_NULL) m_nWidth = 180; else m_nWidth = static_cast< long >(vWidth); if(vHeight.vt == VT_NULL) { SIZE szScreen; cManager::_p->GetScreenSize( &szScreen ); m_nHeight = szScreen.cy/2; } else m_nHeight = static_cast< long >(vHeight); m_strTitle = vTitle.bstrVal; // The properly made schema should have a single control child MSXML::IXMLDOMElementPtr pControl = pRoot->selectSingleNode( _T( "control" ) ); _ASSERTE( pControl.GetInterfacePtr() != NULL ); pControl->QueryInterface( ppRootControl ); } STDMETHODIMP cView::get_Control(BSTR strName, IControl **pVal) { _ASSERTE( strName != NULL ); _ASSERTE( pVal != NULL ); // Search for a matching control name for( cNamedControlList::iterator i = m_controls.begin(); i != m_controls.end(); ++ i ) { if( i->m_strName == _bstr_t( strName ) ) { *pVal = i->m_pControl; ( *pVal )->AddRef(); return S_OK; } } // The name was not found return E_INVALIDARG; } STDMETHODIMP cView::putref_Control(BSTR strName, IControl *newVal) { _ASSERTE( strName != NULL ); // First look for a matching name for( cNamedControlList::iterator i = m_controls.begin(); i != m_controls.end(); ++ i ) { if( i->m_strName == _bstr_t( strName ) ) { if( newVal == NULL ) m_controls.erase( i ); else i->m_pControl = newVal; return S_OK; } } if( newVal == NULL ) // No value to set return S_OK; // Add in a new record cNamedControl nc; nc.m_strName = strName; nc.m_pControl = newVal; m_controls.push_back( nc ); return S_OK; } STDMETHODIMP cView::LoadControl(ILayerSite *pParent, long nID, IUnknown *pSource, long *pAssignedID) { // Usual parameter validation _ASSERTE( pParent != NULL ); _ASSERTE( pSource != NULL ); _ASSERTE( pAssignedID != NULL ); MSXML::IXMLDOMElementPtr pElement = pSource; // Make sure we're starting from the correct tag name _ASSERTE( pElement->tagName == _bstr_t( _T( "control" ) ) ); // Get the progid and make an instance _variant_t strProgID = pElement->getAttribute( _T( "progid" ) ); _ASSERTE( strProgID.vt == VT_BSTR ); CLSID clsid; HRESULT hRes = ::CLSIDFromProgID( strProgID.bstrVal, &clsid ); _ASSERTE( SUCCEEDED( hRes ) ); CComPtr< ILayer > pChildLayer; hRes = ::CoCreateInstance( clsid, NULL, CLSCTX_INPROC_SERVER, IID_ILayer, reinterpret_cast< void ** >( &pChildLayer ) ); _ASSERTE( SUCCEEDED( hRes ) ); // Get some position metrics - note, these are optional and will be // loaded with 0s - this is for cases when the control is formatted // entirely by the parent _variant_t vLeft = pElement->getAttribute( _T( "left" ) ), vTop = pElement->getAttribute( _T( "top" ) ), vWidth = pElement->getAttribute( _T( "width" ) ), vHeight = pElement->getAttribute( _T( "height" ) ), vUnclipped = pElement->getAttribute( _T( "unclipped" ) ), vID = pElement->getAttribute( _T( "ID" ) ); long nRealID = ( vID.vt == VT_NULL ) ? nID : static_cast< long >( vID ); *pAssignedID = nRealID; POINT pt = { ( vLeft.vt != VT_NULL ) ? static_cast< long >( vLeft ) : 0, ( vTop.vt != VT_NULL ) ? static_cast< long >( vTop ) : 0 }; LayerParams lp = { nRealID, { pt.x, pt.y, pt.x + ( ( vWidth.vt != VT_NULL ) ? static_cast< long >( vWidth ) : 0 ), pt.y + ( ( vHeight.vt != VT_NULL ) ? static_cast< long >( vHeight ) : 0 ) }, ( vUnclipped.vt != VT_NULL ) ? 0 : eRenderClipped }; pParent->CreateChild( &lp, pChildLayer ); // Check if this child is named _variant_t vName = pElement->getAttribute( _T( "name" ) ); if( vName.vt == VT_BSTR ) { // Add the named control CComPtr< IControl > pControl; pChildLayer->QueryInterface( &pControl ); putref_Control( vName.bstrVal, pControl ); } // Ok, the child is made - trick it into loading it's own parameters CComPtr< ILayerSchema > pSchema; if( SUCCEEDED( pChildLayer->QueryInterface( &pSchema ) ) ) pSchema->SchemaLoad( this, pSource ); return S_OK; } STDMETHODIMP cView::LoadSchema(BSTR strXMLSchema) { long nPreviousView; m_pRoot->m_pPanel->get_ActiveView( &nPreviousView ); m_pRoot->m_pPanel->RemoveView( m_nViewID ); CComPtr< IUnknown > pRootControl; loadSchema( strXMLSchema, &pRootControl ); // Set the bar params ViewParams vp = { m_nIcon, m_nIconModule, m_strTitle, m_nLeft, m_nTop, m_nWidth, m_nHeight }; m_pRoot->m_pBars->put_Bar( m_nViewID, &vp ); // Last, create all the controls m_pRoot->m_pPanel->LoadView( m_nViewID, this, pRootControl ); if( nPreviousView == m_nViewID ) // Reactivate the view m_pRoot->SelectBar( m_nViewID ); return S_OK; } STDMETHODIMP cView::get_Title(BSTR *pVal) { USES_CONVERSION; *pVal = OLE2BSTR( m_strTitle ); return S_OK; } STDMETHODIMP cView::put_Title(BSTR newVal) { _ASSERTE( newVal != NULL ); m_strTitle = newVal; long nActiveView; m_pRoot->m_pPanel->get_ActiveView( &nActiveView ); ViewParams vp = { m_nIcon, m_nIconModule, m_strTitle, m_nLeft, m_nTop, m_nWidth, m_nHeight }; m_pRoot->m_pBars->put_Bar( m_nViewID, &vp ); // if( nActiveView == m_nViewID ) // Reload the view // m_pRoot->SelectBar( m_nViewID ); return S_OK; } STDMETHODIMP cView::Alert() { return S_OK; } STDMETHODIMP cView::SetIcon(long icon, VARIANT iconlibrary) { USES_CONVERSION; m_nIcon = icon; switch( iconlibrary.vt ) { case VT_ERROR: case VT_EMPTY: case VT_NULL: m_nIconModule = 0; break; case VT_BSTR: m_nIconModule = reinterpret_cast< long >( ::GetModuleHandle( OLE2T( iconlibrary.bstrVal ) ) ); break; default: // Try and convert everything else to a number try { _variant_t v = iconlibrary; m_nIconModule = v; } catch( ... ) { m_nIconModule = 0; return E_INVALIDARG; } break; } long nActiveView; m_pRoot->m_pPanel->get_ActiveView( &nActiveView ); ViewParams vp = { m_nIcon, m_nIconModule, m_strTitle, m_nLeft, m_nTop, m_nWidth, m_nHeight}; m_pRoot->m_pBars->put_Bar( m_nViewID, &vp ); if( nActiveView == m_nViewID ) // Reload the view m_pRoot->SelectBar( m_nViewID ); return S_OK; } STDMETHODIMP cView::Activate() { long nActiveView; m_pRoot->m_pPanel->get_ActiveView( &nActiveView ); if (nActiveView != m_nViewID) { m_pRoot->SelectBar( m_nViewID ); } return S_OK; } STDMETHODIMP cView::Deactivate() { m_pRoot->m_pPanel->Deactivate(); if(cManager::_p->m_pKeyboard!=NULL) { cManager::_p->m_pKeyboard->sendKeyboardEndCapture( VARIANT_TRUE ); cManager::_p->m_pKeyboard=NULL; } return S_OK; } STDMETHODIMP cView::put_Position(LPRECT pVal) { long nActiveView; m_pRoot->m_pPanel->get_ActiveView( &nActiveView ); if( nActiveView == m_nViewID ) { m_nLeft = pVal->left; m_nTop = pVal->top; m_nWidth = pVal->right; m_nHeight = pVal->bottom; ViewParams vp = {m_nIcon, m_nIconModule, m_strTitle, m_nLeft, m_nTop, m_nWidth, m_nHeight}; m_pRoot->m_pPanel->ActivateView(m_nViewID, &vp ); Fire_Activate(); } return S_OK; } STDMETHODIMP cView::get_Position(LPRECT pVal) { pVal->left = m_nLeft; pVal->top = m_nTop; pVal->right = m_nWidth; pVal->bottom = m_nHeight; return S_OK; }