ActiveX获取JavaScript传递的二维数组

此文参考了http://blog.csdn.net/playstudy/article/details/8259737,在此基础上做了改进

// WebDlg.idl : WebDlg 的 IDL 源
//

// 此文件将由 MIDL 工具处理以
// 产生类型库(WebDlg.tlb)和封送处理代码。

#include "olectl.h"
import "oaidl.idl";
import "ocidl.idl";

[
	object,
	uuid(1DC366A1-3040-4376-B4CD-26B0E7032641),
	dual,
	nonextensible,
	pointer_default(unique)
]
interface IGetJavaScriptArray : IDispatch
{
	[id(1)] HRESULT getArrayValue2D([in] VARIANT arrayPoints, [out,retval] LONG *result);
};

[
	uuid(9C070B0B-F506-44C6-8163-CC9C502B12A3),
	version(1.0),
]
library WebDlgLib
{
	importlib("stdole2.tlb");
	[
		uuid(E5466677-5CF1-4870-98EA-01E9C4A198DF),
		control
	]
	coclass GetJavaScriptArray
	{
		[default] interface IGetJavaScriptArray;
	};
};
// GetJavaScriptArray.h : CGetJavaScriptArray 的声明
#pragma once
#include "resource.h"       // 主符号
#include 
#include "WebDlg_i.h"

#if defined(_WIN32_WCE) && !defined(_CE_DCOM) && !defined(_CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA)
#error "Windows CE 平台(如不提供完全 DCOM 支持的 Windows Mobile 平台)上无法正确支持单线程 COM 对象。定义 _CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA 可强制 ATL 支持创建单线程 COM 对象实现并允许使用其单线程 COM 对象实现。rgs 文件中的线程模型已被设置为“Free”,原因是该模型是非 DCOM Windows CE 平台支持的唯一线程模型。"
#endif

using namespace ATL;



// CGetJavaScriptArray
class ATL_NO_VTABLE CGetJavaScriptArray :
	public CComObjectRootEx,
	public IDispatchImpl,
	public IOleControlImpl,
	public IOleObjectImpl,
	public IOleInPlaceActiveObjectImpl,
	public IViewObjectExImpl,
	public IOleInPlaceObjectWindowlessImpl,
	public ISupportErrorInfo,
	public IQuickActivateImpl,
#ifndef _WIN32_WCE
	public IDataObjectImpl,
#endif
	public IProvideClassInfo2Impl<&CLSID_GetJavaScriptArray, NULL, &LIBID_WebDlgLib>,
	public CComCoClass,
	public CComControl
{
public:


	CGetJavaScriptArray()
	{
	}

DECLARE_OLEMISC_STATUS(OLEMISC_RECOMPOSEONRESIZE |
	OLEMISC_CANTLINKINSIDE |
	OLEMISC_INSIDEOUT |
	OLEMISC_ACTIVATEWHENVISIBLE |
	OLEMISC_SETCLIENTSITEFIRST
)

DECLARE_REGISTRY_RESOURCEID(IDR_GETJAVASCRIPTARRAY)


BEGIN_COM_MAP(CGetJavaScriptArray)
	COM_INTERFACE_ENTRY(IGetJavaScriptArray)
	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(ISupportErrorInfo)
	COM_INTERFACE_ENTRY(IQuickActivate)
#ifndef _WIN32_WCE
	COM_INTERFACE_ENTRY(IDataObject)
#endif
	COM_INTERFACE_ENTRY(IProvideClassInfo)
	COM_INTERFACE_ENTRY(IProvideClassInfo2)
END_COM_MAP()

BEGIN_PROP_MAP(CGetJavaScriptArray)
	PROP_DATA_ENTRY("_cx", m_sizeExtent.cx, VT_UI4)
	PROP_DATA_ENTRY("_cy", m_sizeExtent.cy, VT_UI4)
	// 示例项
	// PROP_ENTRY_TYPE("属性名", dispid, clsid, vtType)
	// PROP_PAGE(CLSID_StockColorPage)
END_PROP_MAP()


BEGIN_MSG_MAP(CGetJavaScriptArray)
	CHAIN_MSG_MAP(CComControl)
	DEFAULT_REFLECTION_HANDLER()
END_MSG_MAP()
// 处理程序原型:
//  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* const arr[] =
		{
			&IID_IGetJavaScriptArray,
		};

		for (int i=0; i
// GetJavaScriptArray.cpp : CGetJavaScriptArray 的实现
#include "stdafx.h"
#include "GetJavaScriptArray.h"
#include 


using namespace ATL;


// CGetJavaScriptArray

STDMETHODIMP CGetJavaScriptArray::getArrayValue2D(VARIANT arrayPoints, LONG *result)
{
	if(arrayPoints.vt != VT_DISPATCH){*result = 0; return S_FALSE;} //数据类型不是VT_DISPATCH
	
	int len1 = 0;
	int len2 = 0;
	HRESULT hr = getArrayLength2D(arrayPoints.pdispVal, &len1, &len2);
	if(FAILED(hr)){*result = 0; return S_FALSE;}
	
	//----------------------------------------
	CString str = _T("CGetJavaScriptArray::getArrayValue2D():\n");

	for(long i = 0; i < len1; i++)
	{
		for(long j = 0; j < len2; j++)
		{
			int value = -1;
			getArrayNumberOfIndex2D(arrayPoints.pdispVal, i, j, &value);
			CString str_temp = _T("");
			str_temp.Format(_T("a[%d,%d]=%d\n"), i, j, value);
			str += str_temp;
		}
	}
	
	//----------------------------------------
	this->MessageBoxW(str, _T("ActiveX获取JavaScript传递的二维数组"), MB_OK);

	*result = 1;
	return S_OK;
}


//获取Javascript数组长度
HRESULT CGetJavaScriptArray::getArrayLength1D(IDispatch *pDisp, int *pLength)
{
	BSTR varName = L"length";
	VARIANT varValue;
	DISPPARAMS noArgs = {NULL, NULL, 0, 0};
	DISPID dispId;
	HRESULT hr = 0;
	*pLength = 0;

	hr = pDisp->GetIDsOfNames(IID_NULL, &varName, 1, LOCALE_USER_DEFAULT, &dispId);
	if (FAILED(hr)){return hr;}

	hr = pDisp->Invoke(dispId, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_PROPERTYGET, &noArgs, &varValue, NULL, NULL);
	if(SUCCEEDED(hr))
	{
		*pLength = varValue.intVal;
	}
	return hr;
}


//获取Javascript数组中指定位置的整数元素值
HRESULT CGetJavaScriptArray::getArrayNumberOfIndex1D(IDispatch *pDisp, int index, int *pValue)
{
	CComVariant varName(index, VT_I4); //数组下标
	DISPPARAMS noArgs = {NULL, NULL, 0, 0};
	DISPID dispId;
	VARIANT varValue;
	HRESULT hr = 0;

	varName.ChangeType(VT_BSTR); //将数组下标转为数字型,以进行GetIDsOfNames
	
	hr = pDisp->GetIDsOfNames(IID_NULL, &varName.bstrVal, 1, LOCALE_USER_DEFAULT, &dispId); //获取通过下标访问数组的过程,将过程名保存在dispId中
	if(FAILED(hr)){return hr;}

	hr = pDisp->Invoke(dispId, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_PROPERTYGET, &noArgs, &varValue, NULL, NULL); //调用COM过程,访问指定下标数组元素,根据dispId 将元素值保存在varValue中
	if(SUCCEEDED(hr))
	{
		*pValue = varValue.intVal; //将数组元素按int类型取出
	}
	return hr;
}


// 设置Javascript数组中指定位置的整数元素值
HRESULT CGetJavaScriptArray::setArrayNumberOfIndex1D(IDispatch *pDisp, int index, int value)
{
	CComVariant varName(index, VT_I4);
	DISPID dispId;
	CComVariant varValue;
	HRESULT hr = 0;

	varName.ChangeType(VT_BSTR); // 将数组下标转为数字型,以进行GetIDsOfNames

	hr = pDisp->GetIDsOfNames(IID_NULL, &varName.bstrVal, 1, LOCALE_USER_DEFAULT, &dispId);
	if (FAILED(hr)){return hr;}

	DISPID dispidPut = DISPID_PROPERTYPUT; //put操作
	DISPPARAMS dispparams;
	dispparams.rgvarg = new VARIANTARG[1]; //初始化rgvarg
	dispparams.rgvarg[0].vt = VT_I4; //数据类型
	dispparams.rgvarg[0].intVal = value; //更新值
	dispparams.cArgs = 1; //参数数量
	dispparams.cNamedArgs = 1; //参数名称
	dispparams.rgdispidNamedArgs = &dispidPut; //操作DispId,表明本参数适用于put操作

	hr = pDisp->Invoke(dispId, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYPUT, &dispparams, NULL, NULL, NULL);

	return hr;
}


//获取Javascript数组长度
HRESULT CGetJavaScriptArray::getArrayLength2D(IDispatch *pDisp, int *pLength1, int *pLength2)
{
	BSTR varName = L"length";
	VARIANT varValue;
	DISPPARAMS noArgs = {NULL, NULL, 0, 0};
	DISPID dispId;
	HRESULT hr = 0;
	*pLength1 = 0;
	*pLength2 = 0;

	hr = pDisp->GetIDsOfNames(IID_NULL, &varName, 1, LOCALE_USER_DEFAULT, &dispId);
	if (FAILED(hr)){return hr;}

	hr = pDisp->Invoke(dispId, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_PROPERTYGET, &noArgs, &varValue, NULL, NULL);
	if(SUCCEEDED(hr)){*pLength1 = varValue.intVal;}

	//---------获取第二维长度-----------------------
	if(*pLength1 > 0)
	{
		CComVariant varNameIndex(0, VT_I4); //数组下标
		varNameIndex.ChangeType(VT_BSTR); //将数组下标转为数字型,以进行GetIDsOfNames
		DISPID dispId2;
		VARIANT varValue2;
		hr = pDisp->GetIDsOfNames(IID_NULL, &varNameIndex.bstrVal, 1, LOCALE_USER_DEFAULT, &dispId2); //获取通过下标访问数组的过程,将过程名保存在dispId中
		if(FAILED(hr)){return hr;}
		
		hr = pDisp->Invoke(dispId2, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_PROPERTYGET, &noArgs, &varValue2, NULL, NULL); //调用COM过程,访问指定下标数组元素,根据dispId 将元素值保存在varValue中
		if(FAILED(hr)){return hr;}
		
		if(varValue2.vt != VT_DISPATCH){return S_FALSE;}
		
		IDispatch *pDisp2 = varValue2.pdispVal;

		VARIANT varValue3;
		DISPPARAMS noArgs = {NULL, NULL, 0, 0};
		DISPID dispId3;

		hr = pDisp2->GetIDsOfNames(IID_NULL, &varName, 1, LOCALE_USER_DEFAULT, &dispId3);
		if(FAILED(hr)){return hr;}

		hr = pDisp2->Invoke(dispId3, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_PROPERTYGET, &noArgs, &varValue3, NULL, NULL);
		if(SUCCEEDED(hr)){*pLength2 = varValue3.intVal;}
	}else
	{
		return S_FALSE;
	}
	return hr;
}


//获取Javascript数组中指定位置的整数元素值
HRESULT CGetJavaScriptArray::getArrayNumberOfIndex2D(IDispatch *pDisp, int index1, int index2, int *pValue)
{
	CComVariant varNameIndex1(index1, VT_I4);
	CComVariant varNameIndex2(index2, VT_I4);
	DISPPARAMS noArgs1 = {NULL, NULL, 0, 0};
	DISPID dispId1;
	DISPID dispId2;
	CComVariant varValue1;
	CComVariant varValue2;
	HRESULT hr = 0;

	varNameIndex1.ChangeType(VT_BSTR); //将数组下标转为数字型,以进行GetIDsOfNames
	varNameIndex2.ChangeType(VT_BSTR); //将数组下标转为数字型,以进行GetIDsOfNames

	hr = pDisp->GetIDsOfNames(IID_NULL, &varNameIndex1.bstrVal, 1, LOCALE_USER_DEFAULT, &dispId1);
	if (FAILED(hr)){return hr;}
	
	hr = pDisp->Invoke(dispId1, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_PROPERTYGET, &noArgs1, &varValue1, NULL, NULL); //调用COM过程,访问指定下标数组元素,根据dispId 将元素值保存在varValue中
	if(FAILED(hr)){return hr;}
	
	if(varValue1.vt != VT_DISPATCH){return S_FALSE;} //varValue2.vt为第二维

	//--------------------------------------------
	IDispatch *pDisp2 = varValue1.pdispVal;
	hr = pDisp2->GetIDsOfNames(IID_NULL, &varNameIndex2.bstrVal, 1, LOCALE_USER_DEFAULT, &dispId2);
	if (FAILED(hr)){return hr;}
	
	hr = pDisp2->Invoke(dispId2, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_PROPERTYGET, &noArgs1, &varValue2, NULL, NULL); //调用COM过程,访问指定下标数组元素,根据dispId 将元素值保存在varValue中
	if(FAILED(hr)){return hr;}

	*pValue = varValue2.intVal;

	return S_OK;
}



对象 GetJavaScriptArray 的 ATL 8.0 测试页












运行结果:

ActiveX获取JavaScript传递的二维数组_第1张图片




你可能感兴趣的:(ActiveX获取JavaScript传递的二维数组)