vc打开docx失败

公共马甲0315 2019-09-03 12:50:12

COleVariant varFilePath(szTemplate);
COleVariant covTrue((short)TRUE);
COleVariant covFalse((short)FALSE);
COleVariant covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);

if(!InitAppInstance())
{
myApp->Quit(covFalse,covTrue,covFalse);
return FALSE;
}

spDocs = myApp->GetDocuments();//获得文档对象

//打开模版文档
spDocs->Open(varFilePath,covFalse,covFalse,covFalse,
covOptional,covOptional,covFalse,covOptional,
covOptional,COleVariant(long(1)),covOptional,
covTrue,covOptional,covOptional,covOptional);


如果目标文件为xxx.doc,则打开正常;如果是docx(2010版本)就会报错。
HRESULT _hr = raw_Open(FileName, ConfirmConversions, ReadOnly, AddToRecentFiles, PasswordDocument, PasswordTemplate, Revert, WritePasswordDocument, WritePasswordTemplate, Format, Encoding, Visible, OpenAndRepair, DocumentDirection, NoEncodingDialog, XMLTransform, &_result);
这里的_hr == -2146823137,返回值_result为空。
然后下一行就异常了
return _DocumentPtr(_result, false);
docTest.exe 中的 0x74c55608 处未处理的异常: Microsoft C++ 异常: 内存位置 0x00c0e960 处的 _com_error。

抛出异常的函数体

inline Word::_DocumentPtr Word::Documents::Open ( VARIANT * FileName, VARIANT * ConfirmConversions, VARIANT * ReadOnly, VARIANT * AddToRecentFiles, VARIANT * PasswordDocument, VARIANT * PasswordTemplate, VARIANT * Revert, VARIANT * WritePasswordDocument, VARIANT * WritePasswordTemplate, VARIANT * Format, VARIANT * Encoding, VARIANT * Visible, VARIANT * OpenAndRepair, VARIANT * DocumentDirection, VARIANT * NoEncodingDialog, VARIANT * XMLTransform ) {
struct _Document * _result = 0;
HRESULT _hr = raw_Open(FileName, ConfirmConversions, ReadOnly, AddToRecentFiles, PasswordDocument, PasswordTemplate, Revert, WritePasswordDocument, WritePasswordTemplate, Format, Encoding, Visible, OpenAndRepair, DocumentDirection, NoEncodingDialog, XMLTransform, &_result);
if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this));
return _DocumentPtr(_result, false);
}

在官网上面查看函数的说明,没有看到有价值的信息
https://docs.microsoft.com/zh-cn/office/vba/api/word.documents.open
求指点。

...全文
190 10 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
公共马甲0315 2019-09-07
  • 打赏
  • 举报
回复
引用 6 楼 zgl7903 的回复:
https://blog.csdn.net/zgl7903/article/details/16959523
大侠可否再帮忙看下这里的问题呢? 但是这个函数Find.Execute(FindText、 MatchCase、 MatchWholeWord、 MatchWildcards、 MatchSoundsLike、 MatchAllWordForms、 Forward、 Wrap、 Format、 ReplaceWith、 Replace、 MatchKashida、 MatchDiacritics、 MatchAlefHamza、 MatchControl) 当中的参数Forward好像只能传递0,1 没有其它可选的参数值?就是传递不了图中的那个高级替换选项的“全部”进去?
公共马甲0315 2019-09-07
  • 打赏
  • 举报
回复
引用 8 楼 zgl7903 的回复:
我测试的Open也没问题啊


#import "C:\Program Files\Common Files\Microsoft Shared\OFFICE14\MSO.DLL" rename("RGB", "msRGB")
#import "C:\Program Files\Common Files\Microsoft Shared\VBA\VBA6\VBE6EXT.OLB"
#import "C:\Program Files\Microsoft Office\Office14\MSWORD.OLB" \
  rename("FindText", "msFindText")\
  rename("ExitWindows","msExitWindows")

...

  return 0;
}


好像是我的参数写的不合适的缘故。但不知道为什么,替换操作,无法替换掉页眉里面的文件名。。。只能替换到文件中的内容?
zgl7903 2019-09-07
  • 打赏
  • 举报
回复
我测试的Open也没问题啊


#import "C:\Program Files\Common Files\Microsoft Shared\OFFICE14\MSO.DLL" rename("RGB", "msRGB")
#import "C:\Program Files\Common Files\Microsoft Shared\VBA\VBA6\VBE6EXT.OLB"
#import "C:\Program Files\Microsoft Office\Office14\MSWORD.OLB" \
  rename("FindText", "msFindText")\
  rename("ExitWindows","msExitWindows")

void DumpComError(_com_error &e) 
{
  _bstr_t bstrSource(e.Source());
  _bstr_t bstrDescription(e.Description());

  TCHAR szBuff[1024] = {0};
  _stprintf_s(szBuff, 
    _T("Oops - hit an error!\n")
    _T("\a\tCode = %08lx\n")
    _T("\a\tCode meaning = %s\n")
    _T("\a\tSource = %s\n")
    _T("\a\tDescription = %s\n"),
    e.Error(), 
    e.ErrorMessage(), 
    (LPCTSTR) bstrSource,
    (LPCTSTR) bstrDescription );
  TRACE(szBuff);
  AfxMessageBox(szBuff);
  ASSERT(0);
}

void TestWord()
{
  using namespace Office;
  using namespace Word;
  _ApplicationPtr pApp;
  _DocumentPtr pDoc;
  
  try
  {
    do
    {
      if(pApp.CreateInstance(L"Word.Application") != S_OK)
        break;
      pApp->Visible = true;

      //pDoc = pApp->GetDocuments()->Add();
      _variant_t vtFile("C:\\temp\\Test.docx");
      pDoc = pApp->GetDocuments()->Open( &vtFile );

      {
        Word::LineFormatPtr pLine = pDoc->Shapes->AddLine(100, 100, 100, 200)->Line; //画线
        pLine->PutStyle(msoLineSingle); //Selection.ShapeRange.Line.Style = msoLineSingle //单根线
        pLine->PutWeight(6); //Selection.ShapeRange.Line.Weight = 6# //6磅
        pLine->PutDashStyle(msoLineLongDash); //Selection.ShapeRange.Line.DashStyle = msoLineLongDash //点画线
        pLine->ForeColor->PutRGB( RGB(51, 102, 255) ); // Selection.ShapeRange.Line.ForeColor.RGB = RGB(51, 102, 255) //线颜色

        //两段箭头
        pLine->put_BeginArrowheadStyle(msoArrowheadTriangle); //Selection.ShapeRange.Line.BeginArrowheadStyle = msoArrowheadTriangle
        pLine->put_EndArrowheadStyle(msoArrowheadTriangle); // Selection.ShapeRange.Line.EndArrowheadStyle = msoArrowheadTriangle
        pLine->put_BeginArrowheadWidth(msoArrowheadWidthMedium); //Selection.ShapeRange.Line.BeginArrowheadWidth = msoArrowheadWidthMedium
        pLine->put_BeginArrowheadLength(msoArrowheadLengthMedium); //Selection.ShapeRange.Line.BeginArrowheadLength = msoArrowheadLengthMedium

        //可见
        pLine->PutVisible(msoTrue); //Selection.ShapeRange.Line.Visible = msoTrue

      }

      Sleep(1000);
      pDoc->Save();
      pDoc->Close();

      pApp->Quit();

    }while(0);
  }
  catch(_com_error &e) 
  {
    DumpComError(e); 
  }
}


int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
  OleInitialize(NULL);
  TestWord();
  OleUninitialize();

  return 0;
}


公共马甲0315 2019-09-07
  • 打赏
  • 举报
回复
引用 6 楼 zgl7903 的回复:
https://blog.csdn.net/zgl7903/article/details/16959523
使用add可以打开相应的docx文件,也可以保存成docx文件,但是我需要的功能会失效。请大侠看下我的代码

	spsel->WholeStory();//全选
	spsel->MoveLeft(COleVariant((short)1),COleVariant((short)1),COleVariant((short)0));
	//spsel->Copy();//复制
	//移动到行末
	COleVariant ftext(L"<THEPOCODE>");
	COleVariant covTrue((short)TRUE);
	COleVariant covFalse((short)FALSE);
	COleVariant cov2((short)2);
	COleVariant covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
	COleVariant Rptext(L"SN_TESTINFORMATION");
        
	pFinds = spsel->GetFind();
	pReplaced = pFinds->GetReplacement();
	pFinds->ClearFormatting();
	pReplaced->ClearFormatting();
	BOOL flag = TRUE;
	while(flag)
	{
		flag = pFinds->Execute(
			&ftext,
			covTrue,
			covTrue,
			covFalse,
			covFalse,
			covFalse,
			covTrue,
			covFalse,//wdFindStop,
			covFalse,
			&Rptext,
			cov2,
			covFalse,
			covFalse,
			covFalse,
			covFalse);
	}
如果用open上述功能就正常,但是open不能打开docx文件。。。
公共马甲0315 2019-09-05
  • 打赏
  • 举报
回复
引用 2 楼 蒋晟 的回复:
居然没有写catch _com_error的语句……

请问大侠,这个函数是com组件自动生成的文件msword.tli里面的内容呀,不是我写的代码,怎么catch呢
zgl7903 2019-09-04
  • 打赏
  • 举报
回复
打开docx, Office 必须是2007版本及以上的 try catch 捕捉 _com_error 异常
hhhh63 2019-09-04
  • 打赏
  • 举报
回复
要引用2010以上的库吧
蒋晟 2019-09-03
  • 打赏
  • 举报
回复
居然没有写catch _com_error的语句……
Eleven 2019-09-03
  • 打赏
  • 举报
回复

3,248

社区成员

发帖
与我相关
我的任务
社区描述
ATL,Active Template Library活动(动态)模板库,是一种微软程序库,支持利用C++语言编写ASP代码以及其它ActiveX程序。
社区管理员
  • ATL/ActiveX/COM社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧