閉じる

VC++から Word文書を作成しよう Part1

仕事にて、アプリ(C++)から Wordをいじくる必要が出てきてメモ的な投稿。

Wordのタイプライブラリをインポートしようとして以下の記述をしたところ、「WebPageFontsPtr」が未定義だという。*1

#import "C:\Program Files\Microsoft Office\Office12\MSWORD.OLB"

Debug/msword.tlhを眺めてみたところ、以下の記述があるのに気がついた。

// Cross-referenced type libraries:
//
// #import "C:\Program Files\Common Files\Microsoft Shared\OFFICE12\MSO.DLL"
// #import "C:\Program Files\Common Files\Microsoft Shared\VBA\VBA6\VBE6EXT.OLB"

試しに以下のような記述にしてみたところ、とりあえずエラーは出なくなった。

#import "C:\Program Files\Common Files\Microsoft Shared\OFFICE12\MSO.DLL" auto_rename
#import "C:\Program Files\Common Files\Microsoft Shared\VBA\VBA6\VBE6EXT.OLB" auto_rename
#import "C:\Program Files\Microsoft Office\Office12\MSWORD.OLB" auto_rename

が、「auto_renameなんてしちゃって問題ないのか???」と思い「VBE6EXT.OLB MSWORD.OLB 」辺りで検索してみると IDispEventImpl の使い方がヒットし、そこには以下のような記述があった。

// Paths to required MS OFFICE files.
#define _MSDLL_PATH "C:\Program Files\Common Files\Microsoft Shared\Office12\MSO.DLL"
// Delete the *.tlh files when changing import qualifiers
#import _MSDLL_PATH rename("RGB", "MSRGB") rename("DocumentProperties", "WordDocumentProperties") raw_interfaces_only

#import "C:\Program Files\Common Files\Microsoft Shared\VBA\VBA6\VBE6EXT.OLB" raw_interfaces_only

#define _MSWORDOLB_PATH "C:\Program Files\Microsoft Office\OFFICE12\MSWORD.OLB"
#import _MSWORDOLB_PATH rename("ExitWindows", "WordExitWindows") rename("FindText", "WordFindText") raw_interfaces_only

やっていることは基本的に同じっぽいけど、MSのドキュメントに出てくるぐらいなのでこちらを採用することにして先へ進む。

当初、以下のようなことをいちいち書いていた。

typedef _com_ptr_t<_com_IIID<Word::_Application,&__uuidof(Word::_Application)> > WordApplicationPtr;

しかし、msword.tlhを読んでいくと以下のような記述に行き当たる…「コレってスマートポインタを自動的に定義してくれているのか?」と _COM_SMARTPTR_TYPEDEFの定義*2 を調べてみると、まんま手で書いていたのを自動でやってくれいることがわかった。*3

_COM_SMARTPTR_TYPEDEF(_Application, __uuidof(_Application));

最終的に新規ドキュメント作成&保存するだけのコードは以下のようになった。

2911_6.cpp
#include "stdafx.h"

#import "C:\Program Files\Common Files\Microsoft Shared\OFFICE12\MSO.DLL" rename("RGB", "MSRGB") rename("DocumentProperties", "WordDocumentProperties") raw_interfaces_only
#import "C:\Program Files\Common Files\Microsoft Shared\VBA\VBA6\VBE6EXT.OLB" raw_interfaces_only
#import "C:\Program Files\Microsoft Office\Office12\MSWORD.OLB" rename("ExitWindows", "WordExitWindows") rename("FindText", "WordFindText") named_guids

int _tmain(int argc, _TCHAR* argv[])
{
CoInitialize(NULL);
try{
Word::_ApplicationPtr WordApplication;
HRESULT result;
if(SUCCEEDED(result=WordApplication.CreateInstance(__uuidof(Word::Application)))){
Word::_DocumentPtr WordDocument=WordApplication->Documents->Add();
if(WordDocument){
try{
// 保存
_variant_t FileName(_T("c:\\wordtest"));
_variant_t PdfFileFormat(static_cast<short>(Word::wdFormatPDF));
WordDocument->SaveAs(&FileName,&PdfFileFormat);
_variant_t DocFileFormat(static_cast<short>(Word::wdFormatDocumentDefault));
WordDocument->SaveAs(&FileName,&DocFileFormat);
}catch(_com_error& e){
MessageBox(HWND_DESKTOP,e.ErrorMessage(),_T("Document operate error"),MB_OK);
}
// ドキュメントを閉じる
WordDocument->Close();
}
// アプリケーションを終了する
WordApplication->Quit();
}
}catch(_com_error& e){
MessageBox(HWND_DESKTOP,e.ErrorMessage(),_T("Com Error"),MB_OK);
}
CoUninitialize();
return 0;
}

後はメソッドを調べてごりごりとドキュメントの内容を作っていけば行けそうだ。

当初考えていたよりあっさり出来そうだな。

ちなみに、今回の案件では pdfでの保存も要求されているのだけど、「Word::wdFormatDocumentDefault」を「Word::wdFormatPDF」とするだけで普通に保存できる。
当初、「docと pdfで保存」という要件に対して「pdfは何とかなるけど、docは Wordがインストールされている環境じゃない無理っす」と答えつつ「pdfかぁ 怠い…」と思っていたので「では Word必須ということでかまいません」と来た時は「ラッキー♪」と思ってしまった。


*1 OFFICE12==Office2007ね

*2 comdef.hにて定義

*3 ちなみに、「Word::_Application」は「Word::_ApplicationPtr」として定義される。

VC++から Word文書を作成しよう Part1」への2件のフィードバック

コメントを残す

メールアドレスが公開されることはありません。必須項目には印がついています *

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)