环境:xp,vs2003,word2010
关键字:vc,vba,word,checkbox,InlineShape,OLEFormat,IDispatch,GetObject
错误代码如下:
void CPrintFormByWord::InitControlValue(short nInitValue)
{
ASSERT(NULL!=g_doc);
InlineShapesPtr shapes=g_doc->GetInlineShapes();
long shapesCount =shapes->GetCount();
for(int i=1; i<=shapesCount; i++)
{
InlineShapePtr shape =shapes->Item(i);
Word::WdInlineShapeType shapeType = shape->GetType();
OLEFormatPtr spOleFormat = shape->OLEFormat;
if(NULL==spOleFormat) return ;
_bstr_t bstrClassType = spOleFormat->GetClassType();
CString sClassType((LPTSTR)bstrClassType);
//if(shapeType!=Word::wdInlineShapeOLEControlObject &&
// sClassType!="Forms.CheckBox.1")//非checkbox对象不处理
//{
// continue;
//}
IDispatchPtr pDisp =spOleFormat->GetObject();
CComDispatchDriver ComDisp(pDisp);
CString type =spOleFormat->GetClassType();
CComVariant vtID;
vtID.vt=VT_BSTR;
ComDisp.GetPropertyByName(L"Name", &vtID);
CString temp(_T(vtID.bstrVal));
temp="["+temp+"]";
temp.MakeUpper();
COleVariant vFalse(nInitValue);
ComDisp.PutPropertyByName(L"Value", &vFalse);
}
}
-------------------------------------------------------------------------------------------------------------------------------------------------------
本来想对word里的checkbox控件批量操作,然后在for循环里i=3的时候老报错,设置i==3 continue,然后不报错了
报错堆栈:
msvcr71d.dll!_CxxThrowException(void * pExceptionObject=0x0012f184, const _s__ThrowInfo * pThrowInfo=0x00440a94) + 0x39 C++
test4.exe!_com_raise_error(HRESULT hr=E_NOINTERFACE, IErrorInfo * perrinfo=0x00000000) 行19 C++
test4.exe!_com_issue_errorex(HRESULT hr=E_NOINTERFACE, IUnknown * punk=0x00197e0c, const _GUID & riid={...}) 行67 C++
test4.exe!Word::OLEFormat::GetObjectA() 行1350 C++
> test4.exe!CPrintFormByWord::InitControlValue(short nInitValue=1) 行900 + 0x13 C++
-------------------------------------------------------------------------------------------------------------------------------------------------------
然后觉得i=3应该不是checkbox,故到word里找vba帮助查找InlineShape,发现有一属性
Type返回内嵌形状的类型。只读 WdInlineShapeType 类型。Word 开发人员参考 WdInlineShapeType 枚举指定内嵌形状的形状类型。
版本信息
已添加版本:
wdInlineShapeChart12内嵌图表。 wdInlineShapeDiagram13内嵌关系图。 wdInlineShapeEmbeddedOLEObject1嵌入的 OLE 对象。 wdInlineShapeHorizontalLine6横线。 wdInlineShapeLinkedOLEObject2链接的 OLE 对象。 wdInlineShapeLinkedPicture4链接的图片。 wdInlineShapeLinkedPictureHorizontalLine8带有横线的链接图片。 wdInlineShapeLockedCanvas14锁定的内嵌形状画布。 wdInlineShapeOLEControlObject5OLE 控件对象。 wdInlineShapeOWSAnchor11OWS 锁定标记。 wdInlineShapePicture3图片。 wdInlineShapePictureBullet9用作项目符号的图片。 wdInlineShapePictureHorizontalLine7带有横线的图片。 wdInlineShapeScriptAnchor10脚本定位标记。指与文档一起存储的脚本块的定位标记位置。
另查 OLEFormat
ClassType返回或设置指定的 OLE 对象、图片或域的类型。 String 类型,可读写Word 开发人员参考 OLEFormat.ClassType 属性返回或设置指定的 OLE 对象、图片或域的类型。 String 类型,可读写。语法
表达式.ClassType
表达式 一个代表 OLEFormat 对象的变量。
说明
对于除 DDE 链接之外的其他链接对象,本属性是只读的。
在“插入”菜单上“对象”对话框中“新建”选项卡上的“对象类型”框中可以看到可用应用程序的列表。以嵌入式图形形式插入一个对象,然后查看域代码,可以找到 ClassType 字符串。对象的类类型后面都带有单词“EMBED”或“LINK”。
-------------------------------------------------------------------------------------------------------------------------------------------------------
在程序获取并监视
i!=3时shape->GetType();spOleFormat->GetClassType();
分别为
wdInlineShapeOLEControlObject
Forms.CheckBox.1
i==3时shape->GetType();spOleFormat->GetClassType();
分别为
wdInlineShapeEmbeddedOLEObject
Package
至此,可以用if判断解决问题了,修改代码如下:
void CPrintFormByWord::InitControlValue(short nInitValue)
{
ASSERT(NULL!=g_doc);
InlineShapesPtr shapes=g_doc->GetInlineShapes();
long shapesCount =shapes->GetCount();
for(int i=1; i<=shapesCount; i++)
{
InlineShapePtr shape =shapes->Item(i);
Word::WdInlineShapeType shapeType = shape->GetType();
OLEFormatPtr spOleFormat = shape->OLEFormat;
if(NULL==spOleFormat) return ;
_bstr_t bstrClassType = spOleFormat->GetClassType();
CString sClassType((LPTSTR)bstrClassType);
if(shapeType!=Word::wdInlineShapeOLEControlObject &&
sClassType!="Forms.CheckBox.1")//非checkbox对象不处理
{
continue;
}
IDispatchPtr pDisp =spOleFormat->GetObject();
CComDispatchDriver ComDisp(pDisp);
CString type =spOleFormat->GetClassType();
CComVariant vtID;
vtID.vt=VT_BSTR;
ComDisp.GetPropertyByName(L"Name", &vtID);
CString temp(_T(vtID.bstrVal));
temp="["+temp+"]";
temp.MakeUpper();
COleVariant vFalse(nInitValue);
ComDisp.PutPropertyByName(L"Value", &vFalse);
}
}
未完待续