仕事にて、アプリ(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必須ということでかまいません」と来た時は「ラッキー♪」と思ってしまった。
VC++から Word文書を作成しよう Part2
前回までで空の文書の作成&保存は出来たので内容を作成してゆく。 「Word::_…
VC++から Word文書を作成しよう Part3
用紙の向きを指定するところでひっかかったので番外編。 SyntaxColor:3…