• WPS文本域替换不完全的问题


    前段时间用户反馈我们的一个Active-X控件在对WPS文档进行文本域操作时无法完全替换值,但是在WORD中不存在该问题。通常来说WPS的许多接口都和WORD相同,DISPID也几乎一致(WPS Document的Application的DISPID和WORD不同,一个是0x000003e8而另一个是0×00000001)。于是将替换核心代码抽出做成一个命令行工具进行测试,代码如下:

     2 std::wcout.imbue(std::locale(“chs”));
     3 
     4 #ifndef DEBUG
     5 wcout << *(argv + 1) << endl;
     6 #endif
     7 
     8 CComPtr<IOleObject> pole  = NULL;
     9 CComPtr<IBindCtx> pbctx   = NULL;
    10 CComPtr<IMoniker> pmkfile = NULL;
    11 HRESULT hr = S_OK;
    12 BIND_OPTS bopts = { sizeof(BIND_OPTS), BIND_MAYBOTHERUSER, 0, 10000 };
    13 
    14 #ifdef DEBUG
    15 LPOLESTR pwszFile = _T(“E:\\Test.wps”);
    16 #else
    17 LPOLESTR pwszFile = *(argv + 1);
    18 #endif
    19 
    20 bopts.grfMode = (STGM_TRANSACTED | STGM_SHARE_DENY_WRITE | STGM_READWRITE);
    21 
    22 ::CoInitialize(NULL);
    23 
    24 hr = CreateBindCtx(0, &pbctx);
    25 hr = pbctx->SetBindOptions(&bopts);
    26 hr = CreateFileMoniker(pwszFile, &pmkfile);
    27 hr = pmkfile->BindToObject(pbctx, NULL, IID_IOleObject, (void**)&pole);
    28 
    29 CComPtr<IDispatch> pdisp;
    30 CComPtr<IDispatch> pFields;
    31 
    32 hr = pole.QueryInterface<IDispatch>(&pdisp);
    33 hr = Marshal::GetIDispatchProperty(pdisp, DISP_DOCUMENT_FIELDS, &pFields);
    34 
    35 LONG lCount;
    36 
    37 hr = Marshal::GetCollectionCount(pFields, &lCount);
    38 
    39 printf(“Field count = %ld\r\n”, lCount);
    40 
    41 for (LONG i = 1; i <= lCount; ++i) {
    42 CComPtr<IDispatch> pField, pCode, pResult;
    43 CComBSTR strText;
    44 LONG lStart, lEnd;
    45 
    46 Marshal::GetCollectionItem2(pFields, i, &pField);
    47 Marshal::GetIDispatchProperty(pField, DISP_FIELD_CODE, &pCode);
    48 Marshal::GetBSTRTypeProperty(pCode, DISP_RANGE_TEXT, &strText);
    49 Marshal::GetI8TypeProperty(pCode, DISP_RANGE_START, &lStart);
    50 Marshal::GetI8TypeProperty(pCode, DISP_RANGE_END, &lEnd);
    51 
    52 wcout << lStart << _T(” “) << lEnd << _T(” “);
    53 wcout << wstring(strText) << endl;
    54 
    55 Marshal::GetIDispatchProperty(pField, DISP_FIELD_RANGE, &pResult);
    56 Marshal::PutBSTRTypeProperty(pResult, DISP_RANGE_TEXT, CComBSTR(_T(“hello, world”)));
    57 }
    58 
    59 CComPtr<IPersistFile> ppfile;
    60 
    61 hr = pole.QueryInterface<IPersistFile>(&ppfile);
    62 hr = ppfile->Save(pwszFile, TRUE);
    63 
    64 wcout << _T(“保存成功”) << endl;
    65 
    66 ::CoUninitialize();
    67 
    68 getchar();
    69 
    70 return 0;

    测试环境1:Windows Server 2008 R2 64位 + WPS Office 2009专业版

    测试结果:一个有11个文本域的文档只替换了6个

    测试环境2:Windows Server 2008 32位 + Microsoft Office 2007

    测试结果:一个有11个文本域的文档全部替换成功

    测试环境3:Windows 7 64位 + Microsoft Office 2010

    测试结果:一个有11个文本域的文档全部替换成功

    测试环境4:Windows XP 32位 + WPS Office 2009专业版

    测试结果:一个有11个文本域的文档只替换了6个

    之前金山研发人员确认用WORD的方式没有问题,但多次测试结果表明WORD的文本域替换在WPS中无法完全奏效。WPS需要在设置Result.Text属性前,调用Collapse函数才可以完成替换:pResult.Invoke0(DISP_RANGE_COLLAPSE);

  • 相关阅读:
    web前端的面试真题
    web前端面试真题! 面试的经历和回答只做参考1
    web前端面试真题! 面试的经历和回答只做参考
    html面试资料
    angluar.js的核心介绍
    解决 Chrome支持小于12px 的文字
    div居中效果出现的问题和解决方法
    li和li之间的bug解决方法
    前端面试题笔试考题和答案
    html5新增的标签和使用的方法
  • 原文地址:https://www.cnblogs.com/junchu25/p/2631154.html
Copyright © 2020-2023  润新知