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

注意

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

このメモでは、イン Place 編集に関連する問題と、サーバーで正しいズームとインのサイズ変更を実行する方法について説明します。 インサイト ライセンス認証では、WYSIWYG の概念は、コンテナーとサーバーが互いに連携し、特に OLE 仕様を同じように解釈することでさらに一歩進みます。

インスポット ライセンス認証をサポートするコンテナーとサーバー間の密接な相互作用のため、エンド ユーザーから多くの期待を維持する必要があります。

  • プレゼンテーション表示 (オーバーライドで描画されたメタファイル) は、編集用に描画される場合とまったく同じように見える必要があります (編集ツールが表示されない点 COleServerItem::OnDraw を除く)。

  • コンテナーがズームすると、サーバー ウィンドウも表示されます。

  • コンテナーとサーバーの両方で、同じメトリックを使用して編集するオブジェクトを表示する必要があります。 つまり、ディスプレイ デバイスでレンダリングするときに、1インチあたりの物理ピクセル数ではなく、1 インチあたりの論理ピクセル数に基づくマッピング モードを使用します。

注意

インセット アクティブ化は埋め込み (リンクされていない) 項目にのみ適用されるので、ズームは埋め込みオブジェクトにのみ適用されます。 と の両方に、ズーム COleServerDocCOleServerItem に使用される API が表示されます。 この二分性の理由は、リンク項目と埋め込み項目の両方に対して有効な関数だけが に存在し (これにより共通の実装が可能になります)、埋め込みオブジェクトに対してのみ有効な関数は クラスに存在します (サーバーの観点から見ると、埋め込まれているドキュメントです COleServerItem )。 COleServerDocCOleServerItem

ほとんどの負担はサーバー実装者に対して行います。サーバーはコンテナーのズーム係数を認識し、必要に応じて編集インターフェイスを変更する必要があります。 ただし、コンテナーで使用されているズーム係数はサーバーによってどのように決定されますか

MFC でのズームのサポート

現在のズームファクターは、 を呼び出すことによって決定できます COleServerDoc::GetZoomFactor 。 ドキュメントがインスポット アクティブではない場合にこれを呼び出した場合、常に 100% のズームファクター (または 1:1 の比率) になります。 イン Place Active 中に呼び出した場合、100% 以外の値が返される場合があります。

正しくズームする例については、MFC OLE サンプル HIERSVR を参照してください。 HIERSVR のズームは、テキストとテキストが一般に線形的に拡大縮小されないという事実によって複雑になります (ヒント、入力規則、デザインの幅、高さはすべて問題を複雑にしています)。 それでも、HIERSVR はズームを正しく実装するための妥当な参照であり、MFC Tutorial SCRIBBLE (手順 7) もそうです。

COleServerDoc::GetZoomFactor は、コンテナーから、または クラスと クラスの実装から使用できるさまざまなメトリックに基づいて、ズーム係数 COleServerItem を決定 COleServerDoc します。 つまり、現在のズーム係数は、次の式によって決定されます。

Position Rectangle (PR) / Container Extent (CE)

POSITION RECTANGLE はコンテナーによって決定されます。 が呼び出された場合、インセット アクティブ化中にサーバーに返され、コンテナーが サーバーの を呼び出す際に (を呼び出して) COleClientItem::OnGetItemPositionCOleServerDoc::OnSetItemRects 更新されます COleClientItem::SetItemRects

CONTAINER EXTENT の計算は少し複雑です。 コンテナーが (を呼び出して) を呼び出した場合、CONTAINER EXTENT は、論理インチあたりのピクセル数に基づいてピクセル COleServerItem::OnSetExtentCOleClientItem::SetExtent に変換されます。 コンテナーが SetExtent を呼び出していない場合 (通常はそう)、CONTAINER EXTENT は から返されるサイズです COleServerItem::OnGetExtent 。 そのため、コンテナーが SetExtent を呼び出していない場合、フレームワークは、コンテナーが呼び出した場合、自然エクステントの 100% (から返される値) で呼び出されたと想定します COleServerItem::GetExtent 。 別の方法として、フレームワークでは、コンテナーに項目の 100% (それ以上、それ以下) が表示されているという前提があります。

と は似た名前ですが、項目の同じ属性を操作しない点 COleServerItem::OnSetExtentCOleServerItem::OnGetExtent に注意することが重要です。 OnSetExtent が呼び出され、(ズーム係数に関係なく) コンテナーに表示されるオブジェクトの量がサーバーに知らせ、オブジェクトの理想的なサイズを決定するためにコンテナーによって呼び出 OnGetExtent されます。

関係する各 API を見て、より明確な画像を取得できます。

COleServerItem::OnGetExtent

この関数は、項目の HIMETRIC 単位で "自然なサイズ" を返す必要があります。 "自然なサイズ" を考える最善の方法は、印刷時に表示される可能性があるサイズとして定義する方法です。 ここで返されるサイズは、特定の項目の内容に対して定数です (メタファイルと同様に、特定の項目に対して定数です)。 ズームを項目に適用しても、このサイズは変更されません。 コンテナーが を呼び出すことによって項目に多かれ少なかれスペースを与える場合、通常は変更されません OnSetExtent 。 変更の例としては、コンテナーによって送信された最後のエクステントに基づいてテキストをラップする "余白" 機能を持つ単純なテキスト エディターの場合があります。 サーバーが変更された場合、サーバーはシステム レジストリに OLEMISC_RECOMPOSEONRESIZE ビットを設定する必要があります (このオプションの詳細については、OLE SDK のドキュメントを参照してください)。

COleServerItem::OnSetExtent

この関数は、コンテナーに オブジェクトの "多かれ少なかれ" と表示される場合に呼び出されます。 ほとんどのコンテナーでは、これを呼び出すのは一般的ではありません。 既定の実装では、コンテナーから受け取った最後の値が 'm_sizeExtent' に格納されます。これは、前述の CONTAINER EXTENT 値を計算するときに で COleServerDoc::GetZoomFactor 使用されます。

COleServerDoc::OnSetItemRects

この関数は、ドキュメントがイン Place Active の場合にのみ呼び出されます。 コンテナーが項目の位置または項目に適用されたクリッピングを更新するときに呼び出されます。 上で説明したように、POSITION RECTANGLE は、ズームファクター計算用の分子を提供します。 サーバーは、 を呼び出すことによって、項目の位置の変更を要求できます COleServerDoc::RequestPositionChange 。 コンテナーは、 (を呼び出して) を呼び出すことによって、この OnSetItemRects 要求に応答する場合と応答しない場合があります COleServerItem::SetItemRects

COleServerDoc::OnDraw

をオーバーライドして作成されたメタファイルでは、現在のズーム係数に関係なく、まったく同じメタファイルが生成される点 COleServerItem::OnDraw に気付く必要があります。 コンテナーは、必要に応じてメタファイルをスケーリングします。 これは、ビューとサーバー項目の の OnDraw 重要な区別です OnDraw 。 ビューはズームを処理します。項目はズーム可能なメタファイルを作成し、コンテナーに残して適切なズームを実行します。

サーバーが正しく動作することを確認する最善の方法は、ドキュメントがインサイト アクティブな場合に の実装 COleServerDoc::GetZoomFactor を使用する方法です。

MFC によるサイズ変更In-Placeサポート

MFC は、OLE 2 の仕様で説明されているイン Place サイズ変更インターフェイスを完全に実装します。 ユーザー インターフェイスは、 クラス、カスタム メッセージ、および のこのメッセージWM_SIZECHILD特殊な処理 COleResizeBar によってサポートされます COleIPFrameWnd

このメッセージの処理は、フレームワークによって提供される処理とは異なる方法で実装できます。 前述のように、フレームワークは、サーバーがズームファクターの変更に応答するコンテナーに対してイン Place サイズ変更の結果 — を残します。 コンテナーの処理中に CONTAINER EXTENT と POSITION RECTANGLE の両方を設定してコンテナーが反応する場合 (の呼び出しの結果として呼び出されます)、イン PLACE のサイズ変更により、編集ウィンドウに項目の "多かれ少なかれ" が表示されます。 COleClientItem::OnChangeItemPositionCOleServerDoc::RequestPositionChange の処理中に POSITION RECTANGLE を設定しただけでコンテナーが反応すると、ズームファクターが変更され、項目が "拡大または縮小" COleClientItem::OnChangeItemPosition と表示されます。

サーバーは、このネゴシエーション中に何が起こるかを (ある程度) 制御できます。 たとえば、スプレッドシートでは、ユーザーがイン Place での項目の編集中にウィンドウのサイズを変更するときに、表示するセルの数を多くまたは少なくすることができます。 ワード プロセッサは、"ページ 余白" を変更してウィンドウと同じにし、テキストを新しい余白に再ラップする場合があります。 サーバーは、サイズ変更が完了したら、自然なエクステント (から返されるサイズ) を変更することで COleServerItem::OnGetExtent 、これを実装します。 これにより、POSITION RECTANGLE と CONTAINER EXTENT の両方が同じ量変更され、結果として同じズーム係数が得られるが、表示領域が大きいか小さかったりします。 さらに、 によって生成されたメタファイルには、ドキュメントの多かれ少なかれが表示されます OnDraw 。 この場合、ユーザーが表示領域ではなく項目のサイズを変更すると、ドキュメント自体が変更されます。

カスタム サイズ変更を実装し、クラス内のカスタム メッセージをオーバーライドすることで提供されるWM_SIZECHILD COleResizeBar を活用 COleIPFrameWnd できます。 アプリケーションの詳細については、「テクニカル ノート 24 WM_SIZECHILD」を参照してください

関連項目

番号別テクニカル ノート
カテゴリ別のテクニカル ノート