WordのIDataObject::GetData呼び出しで、DV_E_FORMATETCが返るのを回避したい
Microsoft Wordにdocファイルを読ませて、IDataObject経由でRTFをもらってこようとしています。
そこで、下記のようなコードを書きました。
---
// ※エラー処理を省略
CComPtr<IStorage> pStorage;
CComPtr<IDataObject> spDataObject;
// ストレージの作成
hr = StgCreateDocfile(
NULL, STGM_READWRITE | STGM_TRANSACTED | STGM_SHARE_EXCLUSIVE,
0,
&pStorage);
// オブジェクトを作成
hr = OleCreateFromFile(
CLSID_NULL,
_T("c:\\abc.doc"),
IID_IDataObject,
OLERENDER_DRAW,
NULL,
static_cast<IOleClientSite*>(this), pStorage,
reinterpret_cast<void**>(&spDataObject) );
// FORMATETC構造体の配列をもらってくる
CComPtr<IEnumFORMATETC> pEnumFormatEtc;
hr = spDataObject->EnumFormatEtc( DATADIR_GET, &pEnumFormatEtc );
FORMATETC rgelt[100];
ULONG celtFetched = 0UL;
hr = spEnumFormatEtc->Next( 100, rgelt, &celtFetched );
// もらった配列を列挙しながらRTFフォーマットを探す
for ( size_t i = 0UL; i < celtFetched; ++ i )
{
TCHAR format_name[1024];
(int) GetClipboardFormatName(
rgelt[i].cfFormat,
format_name,
sizeof(format_name) / sizeof(TCHAR) );
if (
_tcscmp( format_name, _T( "Rich Text Format" ) ) != 0 && // Word XP ~ 2007
_tcscmp( format_name, _T( "リッチ テキスト形式" ) ) != 0 // Word 2000
) continue;
#if 0
// RTFフォーマットが見つかったらIDataObject::QueryGetDataを呼んでみる
hr = spDataObject->QueryGetData( &rgelt[i] );
ATLASSERT( SUCCEEDED(hr) ); // Word 2000 だけここで失敗
#endif
// RTFフォーマットが見つかったらIDataObject::GetDataを呼んでみる
STGMEDIUM medium;
hr = spDataObject->GetData( &rgelt[i-1], &medium );
ATLASSERT( SUCCEEDED(hr) ); // Word 2000 だけここで失敗
・・・
}
---
IDataObject::GetDataを呼ぶところは、Word XP, 2003, 2007で成功しています。
Word 2000 だけ失敗するようです。
エラーコードはDV_E_FORMATETCです。
試しに手動でdocファイルをWordで開いて、ドキュメントを全選択して、[Ctrl+C]でクリップボードの中に入れて、
クリップボードのIDataObjectに対してGetDataするとうまくいきます。
(このときは、「Rich Text Format」というフォーマット名で入っています)
なので、私の呼び方(作法的、タイミング的な)がいけないような気がしています。
ちょっとでも気がついたことがあれば教えてください。
よろしくお願いします。