- GIS论坛-GIS空间站 ( http://bbs.gissky.net/Default.asp )
-- 编程技术交流 ( http://bbs.gissky.net/ShowForum.asp?forumid=22 )
--- vbscript传递数组到activex控件 ( http://bbs.gissky.net/ShowPost.asp?id=43576 )
作者:zcgumxh
发表时间:2008-4-1 11:42:32
想建立利用VC6.0和ATL建立一个Activex控件,接收VBscript脚本中传递进来的数组元素值作为坐标显示直线,试验中参考了http://blog.csdn.net/leechy/archive/2004/07/01/31773.aspx,利用VC的variant数据类型接收vbscript的safearray,但试验中老是出错,代码及错误如下: 首先利用Atl Com AppWizard建立ATL工程,然后利用Insert-->New Atl Object建立控件类,选择Control-->Full Control按照默认选项来建立Activex控件类。为接口IDrawLine添加属性(IDL接口定义文件中属性定义)如下: [propput, id(3), helpstring("property InPutVbArray")] HRESULT InPutVbArray([in] VARIANT newVal); 建立控件类CDrawLine的数组成员,利用接口方法(属性)接收脚本传来的数组: int * m_VbIntArray; 在类构造函数中初始化该成员: m_VbIntArray=new int[2]; m_VbIntArray[0]=100; m_VbIntArray[1]=100; CdrawLine的OnDraw方法内容如下: HRESULT OnDraw(ATL_DRAWINFO& di) { RECT& rc = *(RECT*)di.prcBounds; Rectangle(di.hdcDraw, rc.left, rc.top, rc.right, rc.bottom); SetTextColor(di.hdcDraw,RGB(0,255,255)); SetTextAlign(di.hdcDraw, TA_CENTER|TA_BASELINE); LPCTSTR pszText = _T("ATL 3.0 : DrawLine"); TextOut(di.hdcDraw, (rc.left + rc.right) / 2, (rc.top + rc.bottom) / 2, pszText, lstrlen(pszText)); HPEN hPen,hPenOld; hPen = CreatePen( PS_SOLID, 1, RGB(0,255,255) ); hPenOld = (HPEN) SelectObject( di.hdcDraw, &hPen); MoveToEx(di.hdcDraw,rc.left+m_VbIntArray[0], rc.bottom-m_VbIntArray[1], 0 ); LineTo( di.hdcDraw,rc.right, rc.top ); SelectObject(di.hdcDraw, &hPenOld ); DeleteObject(hPen); return S_OK; }
CDrawLine类中接口属性的输入方法及相关函数内容如下: STDMETHODIMP CDrawLine::put_InPutVbArray(VARIANT newVal) { // TODO: Add your implementation code here LPBYTE p ; DWORD nLen; HRESULT hr; hr = VariantArrayToBytes(&newVal, &p, &nLen) ; if( E_INVALIDARG == hr) { m_VbIntArray[0]=0; m_VbIntArray[1]=0; } if( S_OK == hr) { //....... do sth on p for(int i=0;i<2;i++) { m_VbIntArray[i]=(int)p[i]; } delete[] p; } return S_OK; }
HRESULT CDrawLine::VariantArrayToBytes(VARIANT *pVariant, LPBYTE *ppBytes, DWORD *pdwBytes) { USES_CONVERSION; /* if (pVariant->vt != (VT_VARIANT | VT_BYREF)) return E_INVALIDARG; if (!(pVariant->pvarVal->vt & VT_ARRAY)) return E_INVALIDARG;*/ SAFEARRAY* pX = NULL;
/*if (pVariant->pvarVal->vt & VT_BYREF) pX = *(pVariant->pvarVal->pparray); else pX = pVariant->pvarVal->parray; if (::SafeArrayGetDim(pX) != 2) return E_INVALIDARG;*/ pX = pVariant->parray; //pX = pVariant->pvarVal->parray; //pX = *(pVariant->pvarVal->pparray); *ppBytes = NULL; *pdwBytes = 0; VARIANT *pArray = NULL; HRESULT hr = E_FAIL; _variant_t v; hr = SafeArrayAccessData(pX, (void **) &pArray ); if( SUCCEEDED(hr)) { *pdwBytes = pX->rgsabound[0].cElements; *ppBytes = (LPBYTE)new BYTE[*pdwBytes]; for( DWORD i = 0; i < *pdwBytes; i++) { v = pArray[i]; v.ChangeType(VT_UI1); (*ppBytes)[i] = v.bVal; } SafeArrayUnaccessData( pX ); } else return hr; SafeArrayDestroy(pX); return S_OK; }
CDrawLine::VariantArrayToBytes方法中注释掉的内容是因为不注释掉的话后面的部分根本不会执行,程序编译通过,使用html脚本测试: <OBJECT classid="clsid:2E2BEB4E-530F-444B-A987-B151ACFB2499" id="ActivexDemo" > </OBJECT> <SCRIPT LANGUAGE="VBScript"> <!-- dim a a=Array(50,50) //dim a() //redim a(2) //a(0)=50 //a(1)=50 //a(2)=50 ActivexDemo.InPutVbArray=a --> </SCRIPT> 出现不同类型的错误,有兴趣可以试一下。 后改变思路,修改和简化接口属性的输入方法如下: STDMETHODIMP CDrawLine::put_InPutVbArray(VARIANT newVal) { // TODO: Add your implementation code here //deal with vbscript array VARIANT* v=&newVal; SAFEARRAY* pS = v->parray; //SAFEARRAY* pS = v->pvarVal->parray; //SAFEARRAY* pS = *(v->pvarVal->pparray);//error unsigned int cdims; //cdims = SafeArrayGetDim(pS); cdims=pS->cDims; if ( cdims == 1 & pS->rgsabound[0].cElements==4) { USES_CONVERSION; long * pNum; //SafeArrayAccessData(pS, (void**)&pNum); //SafeArrayLock(pS); pNum=(long *)pS->pvData; m_VbIntArray[0]=pNum[2]; m_VbIntArray[1]=pNum[2]; //SafeArrayUnlock(pS); } return S_OK; } 测试脚本如下: <OBJECT classid="clsid:2E2BEB4E-530F-444B-A987-B151ACFB2499" id="ActivexDemo" > </OBJECT> <SCRIPT LANGUAGE="VBScript"> <!-- ActivexDemo.Coordinate=50.0 dim a a=Array(50,50,50,50) ActivexDemo.InPutVbArray=a --> </SCRIPT> 只能取到pNum[2]的值并划线,其它元素值都取不到。而且只能使用Array定义VBscript数组,另外一种定义方法也不行,到底是什么原因也不知道,请高手予以指点。
相关附件
|