テクニカル ノート 40: MFC/OLE 埋め込み先サイズ変更とズーム

更新 : 2007 年 11 月

f7btc8hb.alert_note(ja-jp,VS.90).gifメモ :

次のテクニカル ノートは、最初にオンライン ドキュメントの一部とされてから更新されていません。結果として、一部のプロシージャおよびトピックが最新でないか、不正になります。最新の情報について、オンライン ドキュメントのキーワードで関係のあるトピックを検索することをお勧めします。

このテクニカル ノートでは、埋め込み先編集に関する問題と、サーバーに正しくズームや埋め込み先サイズ変更を行わせる方法について説明します。埋め込み先編集の有効化は、コンテナとサーバーが協力して動作するという WYSIWYG (What You See Is What You Get) の考え方に沿ったもので、OLE の仕様もその方向で設計されています。

埋め込み先編集の有効化をサポートするコンテナとサーバーは密接に連携しています。そのため、ユーザーは次の条件を守ってください。

  • プレゼンテーション ディスプレイ (COleServerItem::OnDraw のオーバーライド関数で描画されるメタファイル) は、編集の場合とまったく同じように表示されるようにしてください (ただし編集ツールを除く)。

  • コンテナがズームすると、サーバーのウィンドウもズームする必要があります。

  • コンテナとサーバーは、同じメトリック (縮尺) を使用してオブジェクトの表示を行ってください。これは、ディスプレイ デバイスにレンダリングするときに、1 インチあたりの論理ピクセル数 (物理ピクセル数ではなく) に基づいたマップ モードが使用されるからです。

f7btc8hb.alert_note(ja-jp,VS.90).gifメモ :

埋め込み先編集の有効化の使用は埋め込まれたオブジェクトに限られるため (リンクされたオブジェクトではできません)、ズームは埋め込みオブジェクトにしか適用できません。ところが、COleServerDocCOleServerItem の両方で API がズームに使用されています。これは、埋め込みオブジェクトとリンク オブジェクトの両方で有効な関数が COleServerItem クラスに含まれていて (共通の実装を使用可能)、埋め込みオブジェクトでのみ有効な関数が COleServerDoc クラスに含まれているためです。サーバー側から見ると、埋め込まれるのはドキュメントです。

サーバーはコンテナのズーム ファクタ (倍率) を認識し、適宜編集インターフェイスを変更する必要がありますが、その作業の大半はサーバーの開発者が行うことになります。次に、コンテナの使用しているズーム ファクタをサーバー側で認識する方法について説明します。

MFC のズームのサポート

現在のズーム ファクタを調べるには COleServerDoc::GetZoomFactor 関数を呼び出します。この関数を埋め込み先編集が有効でない状態で呼び出すと、常に 100% (1:1) が返されます。埋め込み先編集が有効な状態で呼び出すと、100% 以外の値も返されます。

ズームを正しく処理している例として、MFC OLE のサンプル HIERSVR があります。HIERSVR におけるズームは、文字を表示しているため複雑になっています。通常、文字は線形にはスケーリングされません。ヒント、印刷上の規約、デザインの幅と長さなどが原因で、処理が複雑になっているためです。しかし、HIERSVR はズームを正しく実装するための参考になります。同じように、『MFC サンプル』の SCRIBBLE (ステップ 7) も良い例です。

COleServerDoc::GetZoomFactor 関数は、コンテナや COleServerItem クラス、COleServerDoc クラスなどから取得できる各種のメトリックを基にして、ズーム ファクタを計算します。つまり、現在のズームは次の式で計算されます。

Position Rectangle (PR) / Container Extent (CE)

POSITION RECTANGLE は、コンテナによって決定されます。埋め込み先編集の有効化の間に、COleClientItem::OnGetItemPosition 関数の戻り値としてサーバーに返されます。また、コンテナが (COleClientItem::SetItemRects 関数の呼び出しと合わせて) サーバーの COleServerDoc::OnSetItemRects 関数を呼び出すと更新されます。

CONTAINER EXTENT の計算は多少複雑です。コンテナが (COleClientItem::SetExtent 関数の呼び出しと合わせて) COleServerItem::OnSetExtent 関数を呼び出した場合、CONTAINER EXTENT は、1 インチあたりのピクセル数を基に変換された this 値になります。コンテナが SetExtent 関数を呼び出さない場合 (通常は呼び出しません)、CONTAINER EXTENT は COleServerItem::OnGetExtent 関数の返す値となります。したがって、コンテナが SetExtent 関数を呼び出さない場合、フレームワークは、コンテナが自然な範囲 (COleServerItem::GetExtent の戻り値) である 100% をパラメータにして呼び出したものと見なします。つまり、フレームワークはコンテナがアイテムを 100% で表示しているものと見なします。

COleServerItem::OnSetExtent 関数と COleServerItem::OnGetExtent 関数は、似た名前ですが同じ属性を扱いません。OnSetExtent 関数は、ズーム ファクタとは無関係にコンテナでオブジェクトがどの程度表示されているかをサーバーに知らせます。OnGetExtent 関数はコンテナから呼び出され、オブジェクトの本来の論理的なサイズを返します。

関連する各 API について説明します。

COleServerItem::OnGetExtent

この関数は、HIMETRIC 単位で、アイテムの "自然な大きさ" を返します。"自然な大きさ" とは、印刷されたときの大きさです。ここで返される大きさは、特定のアイテムについては常に同じです。メタファイルも特定のアイテムについては常に同じ大きさです。アイテムがズームされていても、この値は変わりません。通常は、コンテナが OnSetExtent 関数を呼び出して大きさを変更しない限り、この値が変わることはありません。自然な大きさの変更の例として、"折り返し" 機能 (コンテナの指定した範囲でテキストを折り返して表示する機能) を持たない簡単なエディタがあります。サーバーが自然な大きさを変更する場合には、システム レジストリの OLEMISC_RECOMPOSEONRESIZE ビットをオンにしておくとよいでしょう。この詳細については、OLE SDK のドキュメントを参照してください。

COleServerItem::OnSetExtent

この関数は、コンテナがオブジェクトの表示範囲を変えようとするときに呼び出されます。ほとんどのコンテナはこの関数を呼び出しません。既定の実装では、直前の呼び出しでコンテナから受け取った値を "m_sizeExtent" に格納します。この変数は COleServerDoc::GetZoomFactor を使用して前の CONTAINER EXTENT を計算するときに使用されます。

COleServerDoc::OnSetItemRects

この関数は、ドキュメントが埋め込み先編集が有効な場合にのみ呼び出されます。コンテナがアイテムの位置やクリッピング領域を変更すると呼び出されます。POSITION RECTANGLE は、前に述べたように、ズーム ファクタの計算に使用されます。サーバーからアイテムの位置の変更を要求するには、COleServerDoc::RequestPositionChange 関数を呼び出します。コンテナは、必要に応じて OnSetItemRects 関数を呼び出して (COleServerItem::SetItemRects 関数も呼び出して)、この要求に答えます。

COleServerDoc::OnDraw

COleServerItem::OnDraw のオーバーライド関数で作成されるメタファイルは、ズーム ファクタとは関係なく、常に同じメタファイルになる、という点が重要です。コンテナはメタファイルを適切にスケーリングします。ビューの OnDraw 関数とサーバー アイテムの OnDraw には違いがあります。ビューはズームを処理しますが、アイテムはズーム可能なメタファイルを作成し、ズーム処理はコンテナに任せます。

サーバーを確実に正しく動作させるには、ドキュメントが埋め込み先編集が有効なときに COleServerDoc::GetZoomFactor 関数を使用します。

MFC による埋め込み先サイズ変更のサポート

MFC には、OLE 2 の仕様どおりに、埋め込み先サイズ変更のインターフェイスが完全に実装されています。COleResizeBar クラスではユーザー インターフェイスがサポートされ、カスタム メッセージ WM_SIZECHILD と、そのメッセージの専用処理は COleIPFrameWnd 関数でサポートされます。

このメッセージをフレームワークの提供する処理とは異なった形で処理することがあります。前に述べたように、フレームワークは埋め込み先サイズ変更の結果については関知しません。サーバーは、ズーム ファクタの変更に応じて処理を行います。コンテナが、COleClientItem::OnChangeItemPosition 関数 (COleServerDoc::RequestPositionChange 関数の呼び出しの結果、呼び出されます) の処理の際に CONTAINER EXTENT と POSITION RECTANGLE の両方を変更した場合には、埋め込み先サイズ変更によって、編集ウィンドウの中でアイテムの表示領域が変わります。コンテナが POSITION RECTANGLE だけを変更した場合、ズーム ファクタが変更し、アイテムは拡大または縮小されて表示されます。

サーバーはある程度までこのようなやり取りを制御できます。たとえば、スプレッドシートは、埋め込み先編集中のウィンドウの大きさが変わると、それに応じて表示されるセルの数を変える必要があります。ワード プロセッサの場合は、ウィンドウの大きさと等しくなるように "ページ マージン" を変更して、テキストを新しいマージンに合わせて表示します。サーバーは、サイズ変更に応じてドキュメントの自然な範囲 (COleServerItem::OnGetExtent の返す値) を変えることにより、そのような動作を実現しています。これによって、POSITION RECTANGLE と CONTAINER EXTENT が同じ量だけ変更されてズーム ファクタが等しくなりますが、表示領域は異なります。さらに、OnDraw で生成されたメタファイルでは、表示されるドキュメントの量が変化します。この場合ユーザーがサイズ変更を行うと、表示領域ではなくドキュメントの大きさ自体が変更されます。

COleIPFrameWnd クラスの WM_SIZECHILD メッセージをオーバーライドすることによってサイズ変更をカスタマイズし、COleResizeBar の提供するユーザー インターフェイスを改良することもできます。WM_SIZECHILD メッセージの詳細仕様については、「テクニカル ノート 24: MFC で定義されているメッセージおよびリソース」を参照してください。

参照

その他の技術情報

番号順テクニカル ノート

カテゴリ別テクニカル ノート