⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 map.cpp

📁 这是非常有挑战性的题目。对于用户输入的任意一个平面函数f(x)
💻 CPP
字号:
// Map.cpp : Implementation of CMap

#include "stdafx.h"
#include "FunMap.h"
#include "Map.h"
#include <math.h>

/////////////////////////////////////////////////////////////////////////////
// CMap

STDMETHODIMP CMap::get_MaxX(double *pVal)
{	//取得属性,X 半轴的最大值
	*pVal = m_xMax;

	return S_OK;
}

STDMETHODIMP CMap::put_MaxX(double newVal)
{	//设置属性,X 半轴的最大值
	m_xMax = fabs( newVal );
	FireViewChange();

	return S_OK;
}

STDMETHODIMP CMap::get_MaxY(double *pVal)
{	//取得属性,Y 半轴的最大值
	*pVal = m_yMax;

	return S_OK;
}

STDMETHODIMP CMap::put_MaxY(double newVal)
{	//设置属性,Y 半轴的最大值
	m_yMax = fabs( newVal );
	FireViewChange();

	return S_OK;
}

STDMETHODIMP CMap::get_Expression(BSTR *pVal)
{	//取得属性,函数式
	*pVal = m_sExpression.Copy();

	return S_OK;
}

STDMETHODIMP CMap::put_Expression(BSTR newVal)
{	//设置属性,函数式
	m_sExpression = newVal;

	if(Calc())
	{
		FireViewChange();
		return S_OK;
	}
	else	return E_INVALIDARG;
}

BOOL CMap::Calc()
{	//根据函数式,计算函数曲线的坐标点
	CComQIPtr< IActiveScript > pAS;
	pAS.CoCreateInstance( L"VBScript" );
	if( !pAS )
	{
		Fire_ScriptErr( CComBSTR( _T("加载 VBScript 引擎失败")) );
		return FALSE;
	}

	CComQIPtr< IActiveScriptParse > pASP(pAS);
	if( !pASP )
	{
		Fire_ScriptErr( CComBSTR( _T("查询解析接口失败")) );
		return FALSE;
	}
	pAS->SetScriptSite( this );

	HRESULT hr = pASP->InitNew();
	if( FAILED(hr) )
	{
		Fire_ScriptErr( CComBSTR( _T("解析接口初始化失败")) );
		pAS->Close();	return FALSE;
	}
   
	hr = pAS->AddNamedItem(L"MyObject", SCRIPTITEM_ISVISIBLE | SCRIPTITEM_ISSOURCE);
	if( FAILED(hr) )
	{
		Fire_ScriptErr( CComBSTR( _T("添加脚本命名错误")) );
		pAS->Close();	return FALSE;
	}

	::memset( m_xVal, 0, sizeof(double) * nPointCount );
	::memset( m_yVal, 0, sizeof(double) * nPointCount );

	USES_CONVERSION;
	for(int i=0; i<nPointCount; i++)
	{
		TCHAR szScript[1000];
		double x=i*(2*m_xMax)/nPointCount-m_xMax;	//求得自变量的值

		char strX[20];		::_gcvt(x,7,strX);

		::wsprintf( szScript,
			_T("i=%d\r\nx=%s\r\ny=%s\r\ncall Result(i,x,y)"),
			i,A2CT(strX),OLE2CT(m_sExpression));
//		::MessageBox(NULL,szScript,_T("生成的脚本程序"),MB_OK);
/*****************************************************************
 生成 VBScript 的样式为: 

 i = 0		'当前正在计算的点的序号(0 ~ 199)
 x = -4.0	'自变量的值(根据序号、窗口范围和X轴坐标范围计算得到)
 y = sin(x)	'用户输入的函数式f(x)
 call Result( i, x, y )		'调用自身对象的函数,保存坐标点

******************************************************************/
		EXCEPINFO ei;
		hr = pASP->ParseScriptText( CComBSTR( szScript ), L"MyObject",
			NULL, NULL, 0, 0, 0, NULL, &ei);
		if( FAILED( hr ) )	continue;

		hr = pAS->SetScriptState( SCRIPTSTATE_CONNECTED );
		if( FAILED( hr ) )	continue;
	}

	pAS->Close();
	return TRUE;
}

// IActiveScriptSite
STDMETHODIMP CMap::GetLCID(/*[out]*/ LCID *plcid)
{	// 取得当前使用的语言环境
	return E_NOTIMPL;	//使用默认的语言
}

STDMETHODIMP CMap::GetItemInfo(/*[in]*/ LPCOLESTR pstrName,
							   /*[in]*/ DWORD dwReturnMask,
							   /*[out]*/ IUnknown **ppunkItem,
							   /*[out]*/ ITypeInfo **ppTypeInfo)
{
	if(ppTypeInfo)
	{	//取得类型信息库,供 VBScript 进行函数解析用
		*ppTypeInfo = NULL;

		if(dwReturnMask & SCRIPTINFO_ITYPEINFO)
		{
			CComPtr< ITypeLib > sptLib;
			::LoadTypeLib( L"FunMap.tlb", &sptLib );	//装载自身的类型库
			if( sptLib )
				sptLib->GetTypeInfo( 0, ppTypeInfo );
		}
	}

	if(ppunkItem)
	{	//取得 IUnknown 指针,供 VBScript 将来的函数调用
		*ppunkItem = NULL;

		if(dwReturnMask & SCRIPTINFO_IUNKNOWN)
		{
			if ( 0 == _wcsicmp( L"MyObject", pstrName ) )
			{
				ControlQueryInterface( IID_IUnknown, (LPVOID *)ppunkItem );
			}
		}
	}

	return S_OK;
}

STDMETHODIMP CMap::GetDocVersionString(/*[out]*/ BSTR *pbstrVersionString)
{
	return E_NOTIMPL;
}

STDMETHODIMP CMap::OnScriptTerminate(/*[in]*/ const VARIANT *pvarResult, /*[in]*/ const EXCEPINFO *pexcepinfo)
{
	return S_OK;
}

STDMETHODIMP CMap::OnStateChange(/*[in]*/ SCRIPTSTATE ssScriptState)
{
	return S_OK;
}

STDMETHODIMP CMap::OnScriptError(/*[in]*/ IActiveScriptError *pase)
{	// 当用户输入了不正确的函数式,或脚本执行的时候出错
	CComBSTR err,msg;
	HRESULT hr = pase->GetSourceLineText( &err );
	if( FAILED(hr) || !err.Length() )
		msg = _T("执行错误");
	else
	{
		msg = _T("语法错误: ");
		msg.AppendBSTR( err );
	}

	Fire_ScriptErr( msg );

	return S_OK;
}

STDMETHODIMP CMap::OnEnterScript(void)
{
	return S_OK;
}

STDMETHODIMP CMap::OnLeaveScript(void)
{
	return S_OK;
}

STDMETHODIMP CMap::Result(long i, double x, double y)
{	// 动态生成的脚本调用该函数,用来保存函数曲线的坐标
	if( ( i >= 0 ) && ( i < nPointCount ) )
	{
		m_xVal[i] = x;
		m_yVal[i] = y;
	}

	return S_OK;
}

STDMETHODIMP CMap::get_Pi(double *pVal)
{	// 取得属性 PI
	*pVal = 3.1415926;

	return S_OK;
}

STDMETHODIMP CMap::Log10(double dbVal, double *pdbVal)
{	// 计算 10 为底的对数
	*pdbVal = ::log10( dbVal );

	return S_OK;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -