vc 设置word里的checkbox报异常(一)

本文解决了在使用VC++操作Word文档中OLE控件时遇到的E_NOINTERFACE错误。通过检查内联形状类型和OLE对象类类型,实现了对CheckBox控件的准确识别。

环境: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);
    }
}

 未完待续

### Java中实现Word文档Checkbox的勾选效果 在Java中处理Word文档时,通常会使用第三方库来实现复杂的操作,例如插入图片、设置页眉页脚、创建表格等。为了在Word文档中实现复选框(Checkbox)的勾选效果,可以借助Apache POI库[^4]。 Apache POI是个强大的Java库,专门用于操作Microsoft Office文件格式,包括Excel、Word和PowerPoint。对于Word文档,POI提供了`XWPFDocument`类来处理`.docx`文件格式。以下是如何在Word文档中插入复选框并设置其勾选状态的详细方法。 #### 使用Apache POI插入复选框 Apache POI支持通过`CTOnOff`类来设置复选框的状态。以下是个代码示例,展示如何在Word文档中插入个复选框,并将其设置为已勾选或未勾选: ```java import org.apache.poi.xwpf.usermodel.*; import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTOnOff; import org.openxmlformats.schemas.wordprocessingml.x2006.main.STOnOff; import java.io.FileOutputStream; import java.io.IOException; public class WordCheckboxExample { public static void main(String[] args) throws IOException { XWPFDocument document = new XWPFDocument(); XWPFParagraph paragraph = document.createParagraph(); XWPFRun run = paragraph.createRun(); // 创建复选框并设置为已勾选 XWPFSDT checkbox = createCheckbox(document, true); paragraph.getCTP().addNewSdt().set(checkbox.getCTSdt()); // 保存文档 try (FileOutputStream out = new FileOutputStream("CheckboxExample.docx")) { document.write(out); } } private static XWPFSDT createCheckbox(XWPFDocument document, boolean isChecked) { XWPFSDT checkbox = new XWPFSDT(new org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSdtBlock(), document); CTOnOff onOff = org.openxmlformats.schemas.wordprocessingml.x2006.main.CTOnOff.Factory.newInstance(); onOff.setVal(isChecked ? STOnOff.ON : STOnOff.OFF); checkbox.getCTSdt().addNewSdtContent().addNewR().addNewFldChar().setOn(onOff); return checkbox; } } ``` #### 代码说明 1. **创建复选框**:通过`XWPFSDT`类创建个结构化文档标签(SDT),并将其作为复选框。 2. **设置勾选状态**:使用`CTOnOff`类来定义复选框的状态。如果`isChecked`为`true`,则设置为已勾选;否则为未勾选。 3. **保存文档**:将生成的文档保存为`.docx`文件。 #### 注意事项 - 确保已添加Apache POI库到项目中。可以通过Maven依赖引入: ```xml <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>5.2.3</version> </dependency> ``` - 如果需要处理更复杂的表单控件,可能需要深入了解`CTSdtBlock`和`CTSdtContent`的相关属性。 ### 相关问题
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值