Chapter.5

より高度な描画を扱う


2004/6/24
 ・サンプルソースで、構造体変数をNewで初期化しているものをNewしないように修正。

1.メタファイルによる描画の限界

今までのサンプルでは、全てメタファイルによる描画を行ってきました。 メタファイルによる描画は、拡大・縮小ともにそこそこの描画速度と品質を保持していると思います。 しかし、小さいスペースに描画されている文字を拡大した場合、その文字間隔が広がりすぎる難点があります。 この文字間隔の問題は、PDFファイルを表示した場合、特に顕著に表れます。 これは実際にOLEサーバが、メタファイルを作成する時に、実際に描画される領域を知らないことが問題です。
OLEサーバが、メタファイルを作成する時に、それが描画される領域を知っていたら・・・、恐らく、この問題は発生しないでしょう。

しかし、IDataObjectは、汎用的なデータ転送を行うためのインターフェースであって、描画を行うインターフェースではありません。 なので、それをIDataObjectに求めるのは、ちょっと無理です。


2.IViewObject

第3章で述べたとおり、描画を行うのはIViewObjectの役割です。 このインターフェースを利用するようにすれば、簡単に解決すると思いがちです。 とりあえず、サンプルを見てみましょう。
VB.NETサンプルソース:chap5.vb.lzh(26KB未満 2004/06/24)

まず、IOleObject.SetExtentを呼び出すところで、エクステントを直接入力できるようにダイアログボックスを表示するように修正してます。 これは、この章のサンプルとして、HTMLファイルを表示しようとした時に、エクステントを手動で設定しないと正常に動作しなかったからです。下が画面のハードコピーです。

PIXEL単位とHIMETRIC単位を相互変換できるように作ってあります。 OLEサーバのエクステントは、HIMETRIC単位で指定しなければならないので、こういった機能が必要となります。

このサンプルを実行するのにちょうど良いのは、HTMLファイルです。URLを指定出来るようになっているので、下のように指定して起動してみて下さい。
chap5.exe http://atata.sakura.ne.jp/net/chap1_1.html
起動直後は何も表示されませんので、エクステントの設定ダイアログで、適切なサイズ(PIXEL単位で640x480程度)を指定して下さい。 すると下記のような画面が表示されます。

スクロールバーのようなものがありますが、それも描画されたものです。操作は出来ません。と言うかウィンドウですらないです。

先ほど述べた通り、IViewObjectインターフェースを取得していますが IViewObjectインターフェースを要求しているところで、例外ハンドラを記述しています。 これは、このインターフェースを実装していないOLEサーバが多数存在するため、インターフェースの取得に失敗して強制終了するのを防ぐためです。
インターフェースの取得に成功した場合、IViewObject.SetAdviseメソッドによって、アドバイザリーシンクを設定しています。


3.まとめ

私が実験した限り、IViewObjectによって描画が行われたのは、HTMLファイルだけでした。 たいていのOLEサーバはローカルサーバ(アウトプロセスサーバ)として実装されています。 ところが、OLEのマーシャラは、IViewObjectをプロセス間でマーシャリングすることが出来ないのです。 理由は簡単で、HDCをマーシャリング出来ないからです(これは、.NET Frameworkで解決されたであろうか・・・?)。 そのため、ローカルサーバは外部にIViewObjectを公開できません。 そういった理由で、大半のOLEサーバは、IViewObjectで描画することが出来ないのです。 (じゃあ、この章の意味は無いんじゃ?とか突っ込まれそうだ・・・)

先ほども少し述べましたが、OLEサーバのエクステントはHIMETRIC単位で扱われます。 これをPIXEL単位と相互に変換するのは、クライアントの役割です。 それで、エクステントとは結局何なのかと言うと、OLEサーバが描画可能な最大サイズと言うことが出来ます。 実際に描画されているオブジェクトのサイズが、このエクステントのサイズより小さいこともあります。 逆にエクステントを超えて描画することは許されていません。
たまに出てくる初期エクステントとは、ファイルが読み込まれた状態でのエクステントのことです。 初期エクステントをサポートしないOLEサーバも存在しています。 HTMLファイルを扱うOLEサーバのように、初期エクステントに1x1を返却するのも許されています。 これは逆にエラーとならない分、クライアント側では扱いづらいと思います。

最後に、oleidl.vbにOLE2UIクラスを追加していますが、これはOLE2の頃に活躍していたライブラリの名前です。 現在では、プラットフォームSDKのサンプルにそれを見つけることが出来ます。 このクラスにクライアントとして必要な機能を随時追加していきます。


前へ 次へ
OLE on .NET Frameworkへ
総合トップへ