home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / mfc / ole / tstcon / script.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1998-03-27  |  12.9 KB  |  589 lines

  1. // Script.Cpp : implementation file
  2. //
  3.  
  4. #include "StdAfx.H"
  5. #include "TestCon.H"
  6.  
  7. #ifdef _DEBUG
  8. #define new DEBUG_NEW
  9. #undef THIS_FILE
  10. static char THIS_FILE[] = __FILE__;
  11. #endif
  12.  
  13. /////////////////////////////////////////////////////////////////////////////
  14. // CScript
  15.  
  16. IMPLEMENT_DYNAMIC( CScript, CCmdTarget )
  17.  
  18. CScript::CScript( CScriptManager* pManager ) :
  19.    m_pManager( pManager )
  20. {
  21.    ASSERT( m_pManager != NULL );
  22. }
  23.  
  24. CScript::~CScript()
  25. {
  26.    Unload();
  27. }
  28.  
  29. HRESULT CScript::AddNamedItem( LPCTSTR pszItemName )
  30. {
  31.    USES_CONVERSION;
  32.    LPCOLESTR pszItemNameO;
  33.    HRESULT hResult;
  34.  
  35.    pszItemNameO = T2COLE( pszItemName );
  36.  
  37.    hResult = m_pActiveScript->AddNamedItem( pszItemNameO,
  38.       SCRIPTITEM_ISSOURCE|SCRIPTITEM_ISVISIBLE );
  39.    if( FAILED( hResult ) )
  40.    {
  41.       return( hResult );
  42.    }
  43.  
  44.    return( S_OK );
  45. }
  46.  
  47. BOOL CScript::FindMacro( LPCTSTR pszMacroName )
  48. {
  49.    DISPID dispid;
  50.  
  51.    ASSERT( pszMacroName != NULL );
  52.  
  53.    return( m_mapMacros.Lookup( pszMacroName, dispid ) );
  54. }
  55.  
  56. POSITION CScript::GetFirstMacroPosition()
  57. {
  58.    return( m_mapMacros.GetStartPosition() );
  59. }
  60.  
  61. CString CScript::GetName()
  62. {
  63.    return( m_strScriptName );
  64. }
  65.  
  66. CString CScript::GetNextMacroName( POSITION& posMacro )
  67. {
  68.    CString strMacro;
  69.    DISPID dispid;
  70.  
  71.    m_mapMacros.GetNextAssoc( posMacro, strMacro, dispid );
  72.  
  73.    return( strMacro );
  74. }
  75.  
  76. HRESULT CScript::LoadScript( LPCTSTR pszFileName, LPCTSTR pszScriptName )
  77. {
  78.    ITypeInfoPtr pTypeInfo;
  79.    HRESULT hResult;
  80.    CLSID clsid;
  81.    CFile file;
  82.    ULONG nFileSize;
  83.    BSTR bstrScript;
  84.    BOOL tSuccess;
  85.    int iMethod;
  86.    UINT nNames;
  87.    BSTR bstrName;
  88.    CString strName;
  89.    CString strExtension;
  90.    int iChar;
  91.  
  92.    ASSERT( pszFileName != NULL );
  93.    ASSERT( pszScriptName != NULL );
  94.    ASSERT( m_pActiveScript == NULL );
  95.  
  96.    iChar = lstrlen( pszFileName )-1;
  97.    while( (iChar >= 0) && (pszFileName[iChar] != _T( '.' )) )
  98.    {
  99.       iChar--;
  100.    }
  101.  
  102.    if( (iChar >= 0) && (lstrcmpi( &pszFileName[iChar], _T( ".js" ) ) == 0) )
  103.    {
  104.       hResult = CLSIDFromProgID( L"JScript", &clsid );
  105.       if( FAILED( hResult ) )
  106.       {
  107.          return( hResult );
  108.       }
  109.    }
  110.    else
  111.    {
  112.       hResult = CLSIDFromProgID( L"VBScript", &clsid );
  113.       if( FAILED( hResult ) )
  114.       {
  115.          return( hResult );
  116.       }
  117.    }
  118.  
  119.    hResult = m_pActiveScript.CreateInstance( clsid, NULL,
  120.       CLSCTX_INPROC_SERVER );
  121.    if( FAILED( hResult ) )
  122.    {
  123.       return( hResult );
  124.    }
  125.  
  126.    m_pActiveScriptParse = m_pActiveScript;
  127.    if( m_pActiveScriptParse == NULL )
  128.    {
  129.       return( E_NOINTERFACE );
  130.    }
  131.  
  132.    hResult = m_pActiveScript->SetScriptSite( &m_xActiveScriptSite );
  133.    if( FAILED( hResult ) )
  134.    {
  135.       return( hResult );
  136.    }
  137.  
  138.    hResult = m_pActiveScriptParse->InitNew();
  139.    if( FAILED( hResult ) )
  140.    {
  141.       return( hResult );
  142.    }
  143.  
  144.    CFileException error;
  145.    tSuccess = file.Open( pszFileName, CFile::modeRead|CFile::shareDenyWrite,
  146.       &error );
  147.    if( !tSuccess )
  148.    {
  149.       return( HRESULT_FROM_WIN32( error.m_lOsError ) );
  150.    }
  151.  
  152.    nFileSize = file.GetLength();
  153.    nFileSize = file.Read( m_strScriptText.GetBuffer( nFileSize ), nFileSize );
  154.    file.Close();
  155.    m_strScriptText.ReleaseBuffer( nFileSize );
  156.    bstrScript = m_strScriptText.AllocSysString();
  157.  
  158.    hResult = m_pActiveScriptParse->ParseScriptText( bstrScript, NULL, NULL,
  159.       NULL, DWORD( this ), 0, SCRIPTTEXT_ISVISIBLE, NULL, NULL );
  160.    SysFreeString( bstrScript );
  161.    if( FAILED( hResult ) )
  162.    {
  163.       return( hResult );
  164.    }
  165.  
  166.    hResult = m_pManager->AddNamedItems( m_pActiveScript );
  167.    if( FAILED( hResult ) )
  168.    {
  169.       return( hResult );
  170.    }
  171.  
  172.    hResult = m_pActiveScript->SetScriptState( SCRIPTSTATE_CONNECTED );
  173.    if( FAILED( hResult ) )
  174.    {
  175.       return( hResult );
  176.    }
  177.  
  178.    hResult = m_pActiveScript->GetScriptDispatch( NULL, &m_pDispatch );
  179.    if( FAILED( hResult ) )
  180.    {
  181.       return( hResult );
  182.    }
  183.  
  184.    hResult = m_pDispatch->GetTypeInfo( 0, GetUserDefaultLCID(), &pTypeInfo );
  185.    if( FAILED( hResult ) )
  186.    {
  187.       return( hResult );
  188.    }
  189.  
  190.    CSmartTypeAttr pTypeAttr( pTypeInfo );
  191.    CSmartFuncDesc pFuncDesc( pTypeInfo );
  192.  
  193.    hResult = pTypeInfo->GetTypeAttr( &pTypeAttr );
  194.    if( FAILED( hResult ) )
  195.    {
  196.       return( hResult );
  197.    }
  198.  
  199.    for( iMethod = 0; iMethod < pTypeAttr->cFuncs; iMethod++ )
  200.    {
  201.       hResult = pTypeInfo->GetFuncDesc( iMethod, &pFuncDesc );
  202.       if( FAILED( hResult ) )
  203.       {
  204.          return( hResult );
  205.       }
  206.  
  207.       if( (pFuncDesc->funckind == FUNC_DISPATCH) && (pFuncDesc->invkind ==
  208.          INVOKE_FUNC) && (pFuncDesc->cParams == 0) )
  209.       {
  210.          bstrName = NULL;
  211.          hResult = pTypeInfo->GetNames( pFuncDesc->memid, &bstrName, 1,
  212.             &nNames );
  213.          if( FAILED( hResult ) )
  214.          {
  215.             return( hResult );
  216.          }
  217.          ASSERT( nNames == 1 );
  218.  
  219.          strName = bstrName;
  220.          SysFreeString( bstrName );
  221.          bstrName = NULL;
  222.  
  223.          // Macros can't contain underscores, since those denote event handlers
  224.          if( strName.Find( _T( '_' ) ) == -1 )
  225.          {
  226.             m_mapMacros.SetAt( strName, pFuncDesc->memid );
  227.          }
  228.       }
  229.  
  230.       pFuncDesc.Release();
  231.    }
  232.  
  233.    m_strScriptName = pszScriptName;
  234.  
  235.    return( S_OK );
  236. }
  237.  
  238. HRESULT CScript::RunMacro( LPCTSTR pszMacroName )
  239. {
  240.    DISPID dispid;
  241.    COleDispatchDriver driver;
  242.    BOOL tFound;
  243.  
  244.    ASSERT( pszMacroName != NULL );
  245.  
  246.    tFound = m_mapMacros.Lookup( pszMacroName, dispid );
  247.    if( !tFound )
  248.    {
  249.       return( DISP_E_MEMBERNOTFOUND );
  250.    }
  251.  
  252.    driver.AttachDispatch( m_pDispatch, FALSE );
  253.    try
  254.    {
  255.       driver.InvokeHelper( dispid, DISPATCH_METHOD, VT_EMPTY, NULL, VTS_NONE );
  256.    }
  257.    catch( COleDispatchException* pException )
  258.    {
  259.       CString strMessage;
  260.  
  261.       AfxFormatString1( strMessage, IDS_DISPATCHEXCEPTION,
  262.          pException->m_strDescription );
  263.       AfxMessageBox( strMessage );
  264.       pException->Delete();
  265.    }
  266.    catch( COleException* pException )
  267.    {
  268.       pException->Delete();
  269.    }
  270.  
  271.    return( S_OK );
  272. }
  273.  
  274. void CScript::Unload()
  275. {
  276.    if( m_pDispatch != NULL )
  277.    {
  278.       m_pDispatch.Release();
  279.    }
  280.    if( m_pActiveScript != NULL )
  281.    {
  282.       m_pActiveScript->SetScriptState( SCRIPTSTATE_DISCONNECTED );
  283.       m_pActiveScript->Close();
  284.       m_pActiveScript.Release();
  285.    }
  286.    if( m_pActiveScriptParse != NULL )
  287.    {
  288.       m_pActiveScriptParse.Release();
  289.    }
  290. }
  291.  
  292.  
  293. BEGIN_INTERFACE_MAP( CScript, CCmdTarget )
  294.    INTERFACE_PART( CScript, IID_IActiveScriptSite, ActiveScriptSite )
  295.    INTERFACE_PART( CScript, IID_IActiveScriptSiteWindow, ActiveScriptSiteWindow )
  296. END_INTERFACE_MAP()
  297.  
  298. BEGIN_MESSAGE_MAP(CScript, CCmdTarget)
  299.     //{{AFX_MSG_MAP(CScript)
  300.         // NOTE - the ClassWizard will add and remove mapping macros here.
  301.     //}}AFX_MSG_MAP
  302. END_MESSAGE_MAP()
  303.  
  304. /////////////////////////////////////////////////////////////////////////////
  305. // CScript message handlers
  306.  
  307.  
  308. ///////////////////////////////////////////////////////////////////////////////
  309. // IActiveScriptSite
  310. ///////////////////////////////////////////////////////////////////////////////
  311.  
  312. STDMETHODIMP_( ULONG ) CScript::XActiveScriptSite::AddRef()
  313. {
  314.    METHOD_PROLOGUE_( CScript, ActiveScriptSite )
  315.  
  316.    TRACE( "XActiveScriptSite::AddRef()\n" );
  317.  
  318.    return( pThis->ExternalAddRef() );
  319. }
  320.  
  321. STDMETHODIMP_( ULONG ) CScript::XActiveScriptSite::Release()
  322. {
  323.    METHOD_PROLOGUE_( CScript, ActiveScriptSite )
  324.  
  325.    TRACE( "XActiveScriptSite::Release()\n" );
  326.  
  327.    return( pThis->ExternalRelease() );
  328. }
  329.  
  330. STDMETHODIMP CScript::XActiveScriptSite::QueryInterface( REFIID iid,
  331.    void** ppInterface )
  332. {
  333.    METHOD_PROLOGUE_( CScript, ActiveScriptSite )
  334.  
  335.    return( pThis->ExternalQueryInterface( &iid, ppInterface ) );
  336. }
  337.  
  338. STDMETHODIMP CScript::XActiveScriptSite::GetDocVersionString(
  339.    BSTR* pbstrVersion )
  340. {
  341.    (void)pbstrVersion;
  342.  
  343.    METHOD_PROLOGUE( CScript, ActiveScriptSite )
  344.  
  345.    return( E_NOTIMPL );
  346. }
  347.  
  348. STDMETHODIMP CScript::XActiveScriptSite::GetItemInfo( LPCOLESTR pszName,
  349.    DWORD dwReturnMask, IUnknown** ppItem, ITypeInfo** ppTypeInfo )
  350. {
  351.    USES_CONVERSION;
  352.    LPCTSTR pszNameT;
  353.    HRESULT hResult;
  354.  
  355.    METHOD_PROLOGUE( CScript, ActiveScriptSite )
  356.  
  357.    if( ppItem != NULL )
  358.    {
  359.       *ppItem = NULL;
  360.    }
  361.    if( ppTypeInfo != NULL )
  362.    {
  363.       *ppTypeInfo = NULL;
  364.    }
  365.  
  366.    if( dwReturnMask&SCRIPTINFO_IUNKNOWN )
  367.    {
  368.       if( ppItem == NULL )
  369.       {
  370.          return( E_POINTER );
  371.       }
  372.    }
  373.    if( dwReturnMask&SCRIPTINFO_ITYPEINFO )
  374.    {
  375.       if( ppTypeInfo == NULL )
  376.       {
  377.          return( E_POINTER );
  378.       }
  379.    }
  380.  
  381.    pszNameT = OLE2CT( pszName );
  382.    TRACE( "XActiveScriptSite::GetItemInfo( %s )\n", pszNameT );
  383.  
  384.    if( dwReturnMask&SCRIPTINFO_IUNKNOWN )
  385.    {
  386.       hResult = pThis->m_pManager->GetItemDispatch( pszNameT, ppItem );
  387.       if( FAILED( hResult ) )
  388.       {
  389.          return( hResult );
  390.       }
  391.    }
  392.    if( dwReturnMask&SCRIPTINFO_ITYPEINFO )
  393.    {
  394.       pThis->m_pManager->GetItemTypeInfo( pszNameT, ppTypeInfo );
  395.    }
  396.  
  397.    return( S_OK );
  398. }
  399.  
  400. STDMETHODIMP CScript::XActiveScriptSite::GetLCID( LCID* plcid )
  401. {
  402.    METHOD_PROLOGUE( CScript, ActiveScriptSite )
  403.  
  404.    if( plcid == NULL )
  405.    {
  406.       return( E_POINTER );
  407.    }
  408.  
  409.    *plcid = GetUserDefaultLCID();
  410.  
  411.    return( S_OK );
  412. }
  413.  
  414. STDMETHODIMP CScript::XActiveScriptSite::OnEnterScript()
  415. {
  416.    METHOD_PROLOGUE( CScript, ActiveScriptSite )
  417.  
  418.    return( S_OK );
  419. }
  420.  
  421. STDMETHODIMP CScript::XActiveScriptSite::OnLeaveScript()
  422. {
  423.    METHOD_PROLOGUE( CScript, ActiveScriptSite )
  424.  
  425.    return( S_OK );
  426. }
  427.  
  428. STDMETHODIMP CScript::XActiveScriptSite::OnScriptError(
  429.    IActiveScriptError* pError )
  430. {
  431.    USES_CONVERSION;
  432.    HRESULT hResult;
  433.    CExcepInfo excep;
  434.    CString strMessage;
  435.    int nResult;
  436.    DWORD dwContext;
  437.    ULONG iLine;
  438.    LONG iChar;
  439.    BSTR bstrSourceLineText;
  440.  
  441.    METHOD_PROLOGUE( CScript, ActiveScriptSite )
  442.  
  443.    TRACE( "XActiveScriptSite::OnScriptError()\n" );
  444.  
  445.    ASSERT( pError != NULL );
  446.  
  447.    hResult = pError->GetSourcePosition( &dwContext, &iLine, &iChar );
  448.    if( SUCCEEDED( hResult ) )
  449.    {
  450.       TRACE( "Error at line %u, character %d\n", iLine, iChar );
  451.    }
  452.    bstrSourceLineText = NULL;
  453.    hResult = pError->GetSourceLineText( &bstrSourceLineText );
  454.    if( SUCCEEDED( hResult ) )
  455.    {
  456.       TRACE( "Source Text: %s\n", OLE2CT( bstrSourceLineText ) );
  457.       SysFreeString( bstrSourceLineText );
  458.       bstrSourceLineText = NULL;
  459.    }
  460.    hResult = pError->GetExceptionInfo( &excep );
  461.    if( SUCCEEDED( hResult ) )
  462.    {
  463.       AfxFormatString2( strMessage, IDS_SCRIPTERRORFORMAT, OLE2CT(
  464.          excep.bstrSource ), OLE2CT( excep.bstrDescription ) );
  465.       nResult = AfxMessageBox( strMessage, MB_YESNO );
  466.       if( nResult == IDYES )
  467.       {
  468.          return( S_OK );
  469.       }
  470.       else
  471.       {
  472.          return( E_FAIL );
  473.       }
  474.    }
  475.  
  476.    return( E_FAIL );
  477. }
  478.  
  479. STDMETHODIMP CScript::XActiveScriptSite::OnScriptTerminate(
  480.    const VARIANT* pvarResult, const EXCEPINFO* pExcepInfo )
  481. {
  482.    (void)pvarResult;
  483.    (void)pExcepInfo;
  484.  
  485.    METHOD_PROLOGUE( CScript, ActiveScriptSite )
  486.  
  487.    TRACE( "XActiveScriptSite::OnScriptTerminate()\n" );
  488.  
  489.    return( S_OK );
  490. }
  491.  
  492. STDMETHODIMP CScript::XActiveScriptSite::OnStateChange(
  493.    SCRIPTSTATE eState )
  494. {
  495.    METHOD_PROLOGUE( CScript, ActiveScriptSite )
  496.  
  497.    TRACE( "XActiveScriptSite::OnStateChange()\n" );
  498.  
  499.    switch( eState )
  500.    {
  501.    case SCRIPTSTATE_UNINITIALIZED:
  502.       TRACE( "\tSCRIPTSTATE_UNINITIALIZED\n" );
  503.       break;
  504.  
  505.    case SCRIPTSTATE_INITIALIZED:
  506.       TRACE( "\tSCRIPTSTATE_INITIALIZED\n" );
  507.       break;
  508.  
  509.    case SCRIPTSTATE_STARTED:
  510.       TRACE( "\tSCRIPTSTATE_STARTED\n" );
  511.       break;
  512.  
  513.    case SCRIPTSTATE_CONNECTED:
  514.       TRACE( "\tSCRIPTSTATE_CONNECTED\n" );
  515.       break;
  516.  
  517.    case SCRIPTSTATE_DISCONNECTED:
  518.       TRACE( "\tSCRIPTSTATE_DISCONNECTED\n" );
  519.       break;
  520.  
  521.    case SCRIPTSTATE_CLOSED:
  522.       TRACE( "\tSCRIPTSTATE_CLOSED\n" );
  523.       break;
  524.  
  525.    default:
  526.       TRACE( "\tUnknown SCRIPTSTATE value\n" );
  527.       ASSERT( FALSE );
  528.       break;
  529.    }
  530.  
  531.    return( S_OK );
  532. }
  533.  
  534.  
  535. ///////////////////////////////////////////////////////////////////////////////
  536. // IActiveScriptSiteWindow
  537. ///////////////////////////////////////////////////////////////////////////////
  538.  
  539. STDMETHODIMP_( ULONG ) CScript::XActiveScriptSiteWindow::AddRef()
  540. {
  541.    METHOD_PROLOGUE_( CScript, ActiveScriptSiteWindow )
  542.  
  543.    TRACE( "XActiveScriptSiteWindow::AddRef()\n" );
  544.  
  545.    return( pThis->ExternalAddRef() );
  546. }
  547.  
  548. STDMETHODIMP_( ULONG ) CScript::XActiveScriptSiteWindow::Release()
  549. {
  550.    METHOD_PROLOGUE_( CScript, ActiveScriptSiteWindow )
  551.  
  552.    TRACE( "XActiveScriptSiteWindow::Release()\n" );
  553.  
  554.    return( pThis->ExternalRelease() );
  555. }
  556.  
  557. STDMETHODIMP CScript::XActiveScriptSiteWindow::QueryInterface(
  558.    REFIID iid, void** ppInterface )
  559. {
  560.    METHOD_PROLOGUE_( CScript, ActiveScriptSiteWindow )
  561.  
  562.    return( pThis->ExternalQueryInterface( &iid, ppInterface ) );
  563. }
  564.  
  565. STDMETHODIMP CScript::XActiveScriptSiteWindow::EnableModeless(
  566.    BOOL tEnable )
  567. {
  568.    (void)tEnable;
  569.  
  570.    METHOD_PROLOGUE( CScript, ActiveScriptSiteWindow )
  571.  
  572.    return( E_NOTIMPL );
  573. }
  574.  
  575. STDMETHODIMP CScript::XActiveScriptSiteWindow::GetWindow(
  576.    HWND* phWindow )
  577. {
  578.    METHOD_PROLOGUE( CScript, ActiveScriptSiteWindow )
  579.  
  580.    if( phWindow == NULL )
  581.    {
  582.       return( E_POINTER );
  583.    }
  584.  
  585.    *phWindow = AfxGetMainWnd()->GetSafeHwnd();
  586.  
  587.    return( S_OK );
  588. }
  589.