書式付き文書を入力するためには、RichTextBox コントロール を使用するのが、とりあえず楽かな、と。問題は、TWIPS で計算するところ。Google で、「twips」を検索すると、ピクセル値に「1400 / PixcelPerInch」を掛けた値を指定すればいいことがわかる。って、画面の「解像度」ですか!?
「インデント」「文字スタイル」などは、プロパティが用意されているので、比較的容易に実現可能。「タブ位置」については、「これからタブ位置は、これこれの位置に指定しますよ」という設定を、まずしておかなければならないらしい。
次に、「絵」。これは、EnableAutoDragDrop プロパティ を True にすれば、自動で出来るらしい。…ダメだ。Word でいうところの、「アイコンで表示」になる。。。Word で作った RTF と、RichTextBox の Rtf プロパティ の内容を比べると、どうも「オブジェクト」ととしてドロップされたらしい。Word では、ドロップされたものを何らかの変換をしているらしい。 とりあえず、RTF の仕様書を調べ、picture に関する記述を見る。ふむふむ。決まり文句を2~3ならべ、16進表記したファイルの内容を並べればいいらしい。
RichTextBox の方は、SelectedRtf プロパティ に、選択されている文字列の RTF 形式が入っており、設定すれば選択されている文字列が置き換わるらしい。なるほど。早速、DragDrop イベント をハンドルして、イメージの RTF 表記を放り込んでみる。
「形式が違います」
なんで?
どうも、完全な RTF を放り込む必要があるらしい。{\rtf1... から書いてある文字列を作り、放り込む。今度は例外が発生しない。が、絵は表示されない。デバッガで追いかけると、次の行に行くと、SelectedRtf プロパティ は元の、何も選択されていない状態に戻っている。なんで?放り込もうとしている RTF をファイルに出して、 Word に読ませると期待通りの結果になるから、ここまでは間違っていないはずなんだけどなぁ。。。→普通に文字を放り込んでみるといけることから、pict のフォーマットが悪いらしい。
SelectedRtf がダメなら、Rtf 自身を編集してやれ!……ダメだ。「カーソルがある位置」を算出するのが面倒くさい。いいや、最後に追加すれば。……これもダメだ。Rtf に放り込んだ次の行で、Rtf が元に戻っている。なんではじかれるんだ?
仕方がないので、検索してみる。みゃみゅ玉子さんところが引っかかった。ひどりさんが、「WebBrowser を使う方が良い」とコメントされている。う~む。そうなのか。
早速、テストアプリを作ってみる。WebBrowser.Uri に、ローカルファイルを指定する。
「このファイルを開くか、または保存しますか?」
って、え??あ、XP SP2 の影響か。しかし、ファイル、つまり項目を切り替えるごとにこれが出てくるのもなぁ。。。とにかく、開く。まぁ、Word があがるんだから、なんだって出来るわな。で、保存...嗚呼、プログラムから制御できないんじゃ?とりあえず、別のファイルを参照させて保存する。そのファイルを開く………えっと、RTF って、テキストファイルの…あ、ASCI 7bit の、可視文字の範囲でファイルが構成されるはずなんですけど???XML 出力したものも同じ。どうも、読み込んだときの形式や拡張子に関係なく、.doc 形式で上書きしているらしいorz 使えんやん!!
VB の大御所、魔界の仮面弁士さんが試してくださったところ、イメージが表示できるとのこと。あれれ?なんで?…その後のやりとりで、魔界の仮面弁士さんは .NET Framework 1.1、私は .NET Framework 2.0β であることが判明。って、1.1 ではドラッグドロップでいけるって??
早速 Virtual PC 2004 に XP と Visual Studio.NET 2003 をインストールし、試す。おわっ!VS.NET2003 では、EnableAutoDragDrop なんて、便利なプロパティがなかった。。。
そういえば、「クリップボードに入れて、ペースト」なんて言葉もあったなぁ、、、と、RichTextBox.Paste メソッド を試してみる。あかん。Win32API 呼び出しでエラーが発生している。しかも、
「FORMATETC 構造体が無効です (HRESULT からの例外: 0x80040064 (DV_E_FORMATETC))」
ってなんですか?そんなプロパティ、設定できませんが?
Word では表示できるなら、Word で読み込んでから保存したものと比べてみよう。ということで、比べてみました。違いは、「nonshppict」という要素のあるなし、だと思うんだけどなぁ。。。えっと、、、「その他のリーダーに対する互換性」…これ?
こまったなぁ。。。WordprocessingML (WordML) 形式で保存(取り出し)できる WYSIWYG なエディット コンポーネントって、ないかしら?やっぱり、OLE 連携は残しておいて欲しかった
せっかくなので、イメージファイルを RTF に変換するコードを貼っておく。イメージは、PNG 形式に変換されます。
private string GetImageByRTF(string fileName) {
System.Text.StringBuilder imgRtf = new StringBuilder();
imgRtf.Append(@"\*\shppict{\pict\pngblip");
// メモリストリームに PNG 形式で保存し、Byte 配列に取り出す
System.IO.MemoryStream memStrm = null;
byte[] imageByteArray;
try {
Image img = null;
memStrm = new System.IO.MemoryStream();
try {
// この辺、無チェックなのは要注意
img = Image.FromFile(fileName);
imgRtf.AppendFormat(@"\picw{0:d}", img.Width);
imgRtf.AppendFormat(@"\pich{0:d}", img.Height);
// ストリームに格納
// windows meta file だといけるのかもしれない。でも、Wmf を指定すると、例外が発生するのよ
img.Save(memStrm, System.Drawing.Imaging.ImageFormat.Png);
memStrm.Flush();
} finally {
if (img != null) { img.Dispose(); }
}
// ストリームから取り出す
memStrm.Position = 0;
imageByteArray = memStrm.ToArray();
memStrm.Close();
} finally {
if (memStrm != null) { memStrm.Dispose(); }
}
// メモリストリームから取り出した Byte 配列を、文字列にする
imgRtf.Append("\n");
for (int idx = 0; idx < imageByteArray.Length; idx++) {
// 適当に改行する方が見やすい(Word 等は 64 バイトごとに改行している)
imgRtf.AppendFormat("{0:x2}", imageByteArray[idx]);
}
imgRtf.Append("}");
string rtf =imgRtf.ToString();
// このままだと RTF じゃないので、RTF の情報を足すこと
return rtf;
}
投稿日時 : 2005年11月12日 6:06