注
次のテクニカル ノートは、最初にオンライン ドキュメントに含まれてから更新されていません。 その結果、一部の手順やトピックが古くなっているか、正しくない可能性があります。 最新情報については、オンライン ドキュメント インデックスで関心のあるトピックを検索することをお勧めします。
このメモでは、インプレース編集に関連する問題と、サーバーで正しいズームとインプレース サイズ変更を実行する方法について説明します。 インプレース アクティブ化では、WYSIWYG の概念は、コンテナーとサーバーが相互に連携し、特に OLE 仕様をほとんど同じように解釈するという点でさらに 1 歩進みます。
インプレース ライセンス認証をサポートするコンテナーとサーバーの間で密接な相互作用があるため、エンド ユーザーからの多くの期待が維持される必要があります。
プレゼンテーション表示 (
COleServerItem::OnDraw
オーバーライドで描画されるメタファイル) は、編集用に描画される場合とまったく同じになります (編集ツールが表示されない点を除く)。コンテナーが拡大すると、サーバー ウィンドウも表示されます。
コンテナーとサーバーの両方に、同じメトリックを使用して編集するためのオブジェクトが表示されます。 つまり、ディスプレイ デバイスでのレンダリング時に、1 インチあたりの物理ピクセル数ではなく、1 インチあたりの 論理 ピクセル数に基づいてマッピング モードを使用します。
注
インプレース アクティブ化は埋め込み (リンクされていない) アイテムにのみ適用されるため、ズームは埋め込みオブジェクトにのみ適用されます。
COleServerDoc
とCOleServerItem
の両方で、ズームに使用される 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)
位置四角形はコンテナーによって決定されます。 これは、 COleClientItem::OnGetItemPosition
が呼び出されたときにインプレース アクティブ化中にサーバーに返され、コンテナーがサーバーの COleServerDoc::OnSetItemRects
を呼び出したときに更新されます ( COleClientItem::SetItemRects
の呼び出しを使用)。
CONTAINER EXTENT は、計算が少し複雑になります。 コンテナーが (COleClientItem::SetExtent
の呼び出しを使用して) COleServerItem::OnSetExtent
を呼び出した場合、CONTAINER EXTENT はこの値を論理インチあたりのピクセル数に基づいてピクセルに変換します。 コンテナーが SetExtent を呼び出していない場合 (通常はそうです)、CONTAINER EXTENT は COleServerItem::OnGetExtent
から返されるサイズです。 そのため、コンテナーが SetExtent を呼び出していない場合、フレームワークは、コンテナーが呼び出した場合、自然エクステントの 100% ( COleServerItem::GetExtent
から返される値) で呼び出したと想定します。 別の方法として、フレームワークは、コンテナーが項目の 100% (それ以上、少なからず) を表示していることを前提としています。
COleServerItem::OnSetExtent
とCOleServerItem::OnGetExtent
の名前は似ていますが、項目の同じ属性を操作しないことに注意してください。
OnSetExtent
は、コンテナーに表示されているオブジェクトの量 (ズーム係数に関係なく) をサーバーに知らせるために呼び出され、 OnGetExtent
はコンテナーによって呼び出され、オブジェクトの理想的なサイズが決定されます。
関連する各 API を見ると、より明確な画像を得ることができます。
COleServerItem::OnGetExtent
この関数は、アイテムの HIMETRIC 単位で "自然なサイズ" を返す必要があります。 "自然なサイズ" と考える最善の方法は、印刷時に表示されるサイズとして定義することです。 ここで返されるサイズは、特定の項目の内容に対して定数です (メタファイルと同じように、特定の項目に対して定数です)。 アイテムにズームを適用しても、このサイズは変更されません。 通常、コンテナーが OnSetExtent
を呼び出すことによって項目に多かれ少なかれスペースを与える場合は変更されません。 変更の例としては、コンテナーによって送信された最後のエクステントに基づいてテキストをラップする "余白" 機能のない単純なテキスト エディターの場合があります。 サーバーが変更された場合、サーバーはシステム レジストリでOLEMISC_RECOMPOSEONRESIZE ビットを設定する必要があります (このオプションの詳細については、OLE SDK のドキュメントを参照してください)。
COleServerItem::OnSetExtent
この関数は、コンテナーにオブジェクトの "多かれ少なかれ" と表示されたときに呼び出されます。 ほとんどのコンテナーでは、これをまったく呼び出しません。 既定の実装では、コンテナーから受信した最後の値が 'm_sizeExtent' に格納されます。これは、前述の CONTAINER EXTENT 値を計算するときに COleServerDoc::GetZoomFactor
で使用されます。
COleServerDoc::OnSetItemRects
この関数は、ドキュメントがインプレースアクティブな場合にのみ呼び出されます。 これは、コンテナーが項目の位置または項目に適用されたクリッピングを更新するときに呼び出されます。 上で説明したように、位置四角形は、ズーム係数の計算に分子を提供します。 サーバーは、 COleServerDoc::RequestPositionChange
を呼び出すことによって項目の位置の変更を要求できます。 コンテナーは、(COleServerItem::SetItemRects
の呼び出しで) OnSetItemRects
を呼び出すことによって、この要求に応答する場合と応答しない場合があります。
COleServerDoc::OnDraw
COleServerItem::OnDraw
のオーバーライドによって作成されたメタファイルは、現在のズーム係数に関係なく、まったく同じメタファイルを生成することを認識することが重要です。 コンテナーは、必要に応じてメタファイルをスケーリングします。 これは、ビューの OnDraw
とサーバーアイテムの OnDraw
の重要な違いです。 ビューはズームを処理し、項目は ズーム可能な メタファイルを作成し、適切なズームを行うためにコンテナーに残します。
サーバーが正しく動作することを保証する最善の方法は、ドキュメントがインプレースアクティブな場合に COleServerDoc::GetZoomFactor
の実装を使用することです。
In-Place サイズ変更の MFC サポート
MFC は、OLE 2 仕様の説明に従って、インプレース サイズ変更インターフェイスを完全に実装します。 ユーザー インターフェイスは、 COleResizeBar
クラス、カスタム メッセージ WM_SIZECHILD、および COleIPFrameWnd
でのこのメッセージの特別な処理によってサポートされます。
このメッセージの処理は、フレームワークによって提供される処理とは異なる場合があります。 前述のように、フレームワークはインプレースサイズの結果をコンテナーまで残します。サーバーはズーム係数の変更に応答します。 コンテナーが COleClientItem::OnChangeItemPosition
の処理中に CONTAINER EXTENT と POSITION RECTANGLE の両方を設定して反応した場合 ( COleServerDoc::RequestPositionChange
の呼び出しの結果として呼び出されます)、インプレース サイズ変更により、編集ウィンドウに項目の "多かれ少なかれ" が表示されます。
COleClientItem::OnChangeItemPosition
の処理中に POSITION RECTANGLE を設定するだけでコンテナーが反応すると、ズーム係数が変更され、項目が "拡大または縮小" と表示されます。
サーバーは、このネゴシエーション中に何が起こるかを (ある程度) 制御できます。 たとえば、スプレッドシートでは、アイテムのインプレース編集中にユーザーがウィンドウのサイズを変更するときに、表示するセルの数を増減できます。 ワード プロセッサでは、"ページの余白" を変更してウィンドウと同じにし、テキストを新しい余白にラップし直す場合があります。 サーバーは、サイズ変更の実行時に自然なエクステント ( COleServerItem::OnGetExtent
から返されるサイズ) を変更することによってこれを実装します。 これにより、位置 RECTANGLE と CONTAINER EXTENT の両方が同じ量だけ変化し、同じズーム係数になりますが、表示領域が大きいか小さくなります。 さらに、ドキュメントの多かれ少なかれ、 OnDraw
によって生成されたメタファイルに表示されます。 この場合、表示領域だけでなく、ユーザーがアイテムのサイズを変更すると、ドキュメント自体が変更されます。
カスタムサイズ変更を実装し、COleIPFrameWnd
クラスのWM_SIZECHILD メッセージをオーバーライドすることで、COleResizeBar
によって提供されるユーザー インターフェイスを引き続き利用できます。 WM_SIZECHILDの詳細については、 テクニカル ノート 24 を参照してください。