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

📄 map.h

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

#ifndef __MAP_H_
#define __MAP_H_

#include "resource.h"       // main symbols
#include <atlctl.h>
#include <activscp.h>
#include "FunMapCP.h"

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

const int nPointCount = 200;	// 计算 X 方向200个点

class ATL_NO_VTABLE CMap : 
	public CComObjectRootEx<CComSingleThreadModel>,
	public CStockPropImpl<CMap, IMap, &IID_IMap, &LIBID_FUNMAPLib>,
	public CComControl<CMap>,
	public IPersistStreamInitImpl<CMap>,
	public IOleControlImpl<CMap>,
	public IOleObjectImpl<CMap>,
	public IOleInPlaceActiveObjectImpl<CMap>,
	public IViewObjectExImpl<CMap>,
	public IOleInPlaceObjectWindowlessImpl<CMap>,
	public ISupportErrorInfo,
	public IConnectionPointContainerImpl<CMap>,
	public IPersistStorageImpl<CMap>,
	public ISpecifyPropertyPagesImpl<CMap>,
	public IQuickActivateImpl<CMap>,
	public IDataObjectImpl<CMap>,
	public IProvideClassInfo2Impl<&CLSID_Map, &DIID__IMapEvents, &LIBID_FUNMAPLib>,
	public IPropertyNotifySinkCP<CMap>,
	public CComCoClass<CMap, &CLSID_Map>,
	public IPersistPropertyBagImpl<CMap>,	// 手工添加持续性属性包的接口
	public IActiveScriptSite,				// 手工添加脚本主机的接口
	public CProxy_IMapEvents< CMap >
{
public:
	CMap()
	{
		m_clrBackColor = RGB( 0, 0, 0 );			// 默认背景(黑)
		m_clrBorderColor = RGB( 128, 128, 128 );	// 默认坐标线(灰)
		m_clrForeColor = RGB( 255, 255, 0 );		// 默认函数曲线(黄)

		m_xMax=4.0;		// 默认 X 轴范围 [-4.0 , +4.0]
		m_yMax=1.0;		// 默认 Y 轴范围 [-1.0 , +1.0]

		// 清空坐标点数据
		::memset( m_xVal, 0, sizeof(double) * nPointCount );
		::memset( m_yVal, 0, sizeof(double) * nPointCount );
	}

DECLARE_REGISTRY_RESOURCEID(IDR_MAP)

DECLARE_PROTECT_FINAL_CONSTRUCT()

BEGIN_COM_MAP(CMap)
	COM_INTERFACE_ENTRY(IMap)
	COM_INTERFACE_ENTRY(IDispatch)
	COM_INTERFACE_ENTRY(IViewObjectEx)
	COM_INTERFACE_ENTRY(IViewObject2)
	COM_INTERFACE_ENTRY(IViewObject)
	COM_INTERFACE_ENTRY(IOleInPlaceObjectWindowless)
	COM_INTERFACE_ENTRY(IOleInPlaceObject)
	COM_INTERFACE_ENTRY2(IOleWindow, IOleInPlaceObjectWindowless)
	COM_INTERFACE_ENTRY(IOleInPlaceActiveObject)
	COM_INTERFACE_ENTRY(IOleControl)
	COM_INTERFACE_ENTRY(IOleObject)
	COM_INTERFACE_ENTRY(IPersistStreamInit)
	COM_INTERFACE_ENTRY2(IPersist, IPersistStreamInit)
	COM_INTERFACE_ENTRY(ISupportErrorInfo)
	COM_INTERFACE_ENTRY(IConnectionPointContainer)
	COM_INTERFACE_ENTRY(ISpecifyPropertyPages)
	COM_INTERFACE_ENTRY(IQuickActivate)
	COM_INTERFACE_ENTRY(IPersistStorage)
	COM_INTERFACE_ENTRY(IDataObject)
	COM_INTERFACE_ENTRY(IProvideClassInfo)
	COM_INTERFACE_ENTRY(IProvideClassInfo2)
	COM_INTERFACE_ENTRY(IPersistPropertyBag)	// 添加持续性属性包接口
	COM_INTERFACE_ENTRY(IActiveScriptSite)		// 添加脚本主机接口
	COM_INTERFACE_ENTRY_IMPL(IConnectionPointContainer)
END_COM_MAP()

BEGIN_PROP_MAP(CMap)
	PROP_DATA_ENTRY("_cx", m_sizeExtent.cx, VT_UI4)
	PROP_DATA_ENTRY("_cy", m_sizeExtent.cy, VT_UI4)
	PROP_ENTRY("Expression", 1, CLSID_MapPP)		// 属性:函数式
	PROP_ENTRY("MaxX", 2, CLSID_MapPP)				// 属性:X半轴最大值
	PROP_ENTRY("MaxY", 3, CLSID_MapPP)				// 属性:Y半轴最大值
	PROP_ENTRY("BackColor", DISPID_BACKCOLOR, CLSID_StockColorPage)
	PROP_ENTRY("BorderColor", DISPID_BORDERCOLOR, CLSID_StockColorPage)
	PROP_ENTRY("ForeColor", DISPID_FORECOLOR, CLSID_StockColorPage)
	// Example entries
	// PROP_ENTRY("Property Description", dispid, clsid)
	// PROP_PAGE(CLSID_StockColorPage)
END_PROP_MAP()

BEGIN_CATEGORY_MAP(CMap)		// 添加脚本安全组件类型
	IMPLEMENTED_CATEGORY(CATID_SafeForScripting)
	IMPLEMENTED_CATEGORY(CATID_SafeForInitializing)
END_CATEGORY_MAP()

BEGIN_CONNECTION_POINT_MAP(CMap)
	CONNECTION_POINT_ENTRY(IID_IPropertyNotifySink)
	CONNECTION_POINT_ENTRY(DIID__IMapEvents)
END_CONNECTION_POINT_MAP()

BEGIN_MSG_MAP(CMap)
	CHAIN_MSG_MAP(CComControl<CMap>)
	DEFAULT_REFLECTION_HANDLER()
END_MSG_MAP()
// Handler prototypes:
//  LRESULT MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
//  LRESULT CommandHandler(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
//  LRESULT NotifyHandler(int idCtrl, LPNMHDR pnmh, BOOL& bHandled);



// ISupportsErrorInfo
	STDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid)
	{
		static const IID* arr[] = 
		{
			&IID_IMap,
		};
		for (int i=0; i<sizeof(arr)/sizeof(arr[0]); i++)
		{
			if (InlineIsEqualGUID(*arr[i], riid))
				return S_OK;
		}
		return S_FALSE;
	}

// IViewObjectEx
	DECLARE_VIEW_STATUS(VIEWSTATUS_SOLIDBKGND | VIEWSTATUS_OPAQUE)

// IActiveScriptSite	添加脚本主机接口的方法声明
	STDMETHOD(GetLCID)(/*[out]*/ LCID *plcid);
	STDMETHOD(GetItemInfo)(/*[in]*/ LPCOLESTR pstrName, /*[in]*/ DWORD dwReturnMask, /*[out]*/ IUnknown **ppunkItem, /*[out]*/ ITypeInfo **ppTypeInfo);
	STDMETHOD(GetDocVersionString)(/*[out]*/ BSTR *pbstrVersionString);
	STDMETHOD(OnScriptTerminate)(/*[in]*/ const VARIANT *pvarResult, /*[in]*/ const EXCEPINFO *pexcepinfo);
	STDMETHOD(OnStateChange)(/*[in]*/ SCRIPTSTATE ssScriptState);
	STDMETHOD(OnScriptError)(/*[in]*/ IActiveScriptError *pase);
	STDMETHOD(OnEnterScript)(void);
	STDMETHOD(OnLeaveScript)(void);

// IMap
public:
	// 脚本扩展方法:计算10为底的对数
	STDMETHOD(Log10)(/*[in]*/ double dbVal, /*[out,retval]*/ double * pdbVal);
	// 脚本扩展属性:只读属性 PI
	STDMETHOD(get_Pi)(/*[out, retval]*/ double *pVal);
	// 脚本扩展方法:用来保存脚本计算后的函数曲线坐标点
	// i: 第几个点		x: 自变量			y: 因变量
	STDMETHOD(Result)(/*[in]*/ long i, /*[in]*/ double x, /*[in]*/ double y);

	// 属性读写函数
	STDMETHOD(get_Expression)(/*[out, retval]*/ BSTR *pVal);
	STDMETHOD(put_Expression)(/*[in]*/ BSTR newVal);
	STDMETHOD(get_MaxY)(/*[out, retval]*/ double *pVal);
	STDMETHOD(put_MaxY)(/*[in]*/ double newVal);
	STDMETHOD(get_MaxX)(/*[out, retval]*/ double *pVal);
	STDMETHOD(put_MaxX)(/*[in]*/ double newVal);

	double m_xMax;					// 保存属性 X 半轴的最大值
	double m_yMax;					// 保存属性 Y 半轴的最大值
	double m_xVal[nPointCount];		// 自变量点
	double m_yVal[nPointCount];		// 因变量点
	CComBSTR m_sExpression;			// 函数式

	HRESULT OnDraw(ATL_DRAWINFO& di)
	{
		// 取得绘图范围
		RECT& rc = *(RECT*)di.prcBounds;
		// 计算坐标原点
		long x = rc.left + ( rc.right - rc.left )/2;
		long y = rc.top + ( rc.bottom - rc.top )/2;
		// 用背景颜色填充
		COLORREF clr;
		::OleTranslateColor( m_clrBackColor, NULL, &clr);
		HBRUSH hbr = ::CreateSolidBrush( clr );
		hbr = (HBRUSH)::SelectObject( di.hdcDraw, hbr );
		Rectangle( di.hdcDraw, rc.left, rc.top, rc.right, rc.bottom );
		hbr = (HBRUSH)::SelectObject( di.hdcDraw, hbr );
		::DeleteObject( hbr );
		// 绘制坐标线
		::OleTranslateColor( m_clrBorderColor, NULL, &clr );
		HPEN hPen = ::CreatePen( PS_SOLID, 0, clr );
		hPen = (HPEN)::SelectObject( di.hdcDraw, hPen );
		// 画 X 轴
		::MoveToEx( di.hdcDraw, rc.left, y, NULL );
		::LineTo( di.hdcDraw, rc.right, y );
		// 画 X 轴上的箭头
		::SetPixel( di.hdcDraw, rc.right-2, y-1, clr );
		::SetPixel( di.hdcDraw, rc.right-3, y-1, clr );
		::SetPixel( di.hdcDraw, rc.right-3, y-2, clr );
		::SetPixel( di.hdcDraw, rc.right-4, y-1, clr );
		::SetPixel( di.hdcDraw, rc.right-4, y-2, clr );
		::SetPixel( di.hdcDraw, rc.right-4, y-3, clr );

		// 画 Y 轴
		::MoveToEx( di.hdcDraw, x, rc.top, NULL );
		::LineTo( di.hdcDraw, x, rc.bottom );
		// 画 Y 轴上的箭头
		::SetPixel( di.hdcDraw, x-1, rc.top+1, clr );
		::SetPixel( di.hdcDraw, x-1, rc.top+2, clr );
		::SetPixel( di.hdcDraw, x-2, rc.top+2, clr );
		::SetPixel( di.hdcDraw, x-1, rc.top+3, clr );
		::SetPixel( di.hdcDraw, x-2, rc.top+3, clr );
		::SetPixel( di.hdcDraw, x-3, rc.top+3, clr );

		hPen = (HPEN)::SelectObject( di.hdcDraw, hPen );
		::DeleteObject( hPen );

		// 绘制函数曲线坐标点
		::OleTranslateColor( m_clrForeColor, NULL, &clr );
		for( int i=0; i<nPointCount; i++ )
		{
			long xPos = (long)( x + ( rc.right - rc.left ) * m_xVal[i] / (m_xMax*2) );
			long yPos = (long)( y - ( rc.bottom - rc.top ) * m_yVal[i] / (m_yMax*2) );

			if(xPos>=rc.left && xPos<rc.right &&
				yPos>=rc.top && yPos<rc.bottom)
			{
				::SetPixel( di.hdcDraw, xPos, yPos, clr );
			}
		}

		return S_OK;
	}
	OLE_COLOR m_clrBackColor;		// 背景色
	OLE_COLOR m_clrBorderColor;		// 坐标线颜色
	OLE_COLOR m_clrForeColor;		// 函数曲线颜色

private:
	BOOL Calc();	// 计算函数曲线的坐标函数
};

#endif //__MAP_H_

⌨️ 快捷键说明

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