Win32 API 日本語リファレンス
ホームSystem.Ole › IViewObjectEx

IViewObjectEx

COM
IID3af24292-0c96-11ce-a0cf-00aa00600ab8継承元IViewObject2自前メソッド開始 vtbl10

公式ドキュメント

IViewObject2 から派生した拡張インターフェースで、非矩形オブジェクトや透明オブジェクトに対する拡張されたちらつきのない描画、非矩形オブジェクトのヒットテスト、およびコントロールのサイズ変更をサポートします。

メソッド 5

vtbl = vtable インデックス(0始まり)。HSP等からCOMメソッドをインデックス指定で呼ぶ際に使用します。0〜2 は IUnknown。

vtbl 10 HRESULT GetRect(DWORD dwAspect, RECTL* pRect)

要求された描画アスペクトを表す矩形を取得します。

dwAspectDWORDin要求された描画アスペクト。
pRectRECTL*out要求された描画アスペクトを表す矩形へのポインター。

戻り値

成功した場合、このメソッドは S_OK を返します。その他に返される可能性のある値には次のものがあります。

戻り値 説明
DV_E_DVASPECT
このメソッドは指定されたアスペクトをサポートしていません。オブジェクトが要求されたアスペクトをサポートしていないか、アスペクトが矩形ではありません。

解説(Remarks)

このメソッドは、指定された描画アスペクトを表す矩形を返します。返される矩形は HIMETRIC 単位で、オブジェクトの原点からの相対位置です。返される矩形は描画アスペクトに応じて次のようになります。

描画アスペクト 説明
DVASPECT_CONTENT オブジェクトはオブジェクト全体のバウンディング矩形を返す必要があります。左上隅はオブジェクトの原点にあり、サイズは IViewObject2::GetExtent が返す範囲(extent)と等しくなります。
DVASPECT_OPAQUE 矩形の不透明領域を持つオブジェクトは、その矩形を返す必要があります。それ以外のオブジェクトは失敗し、エラーコード DV_E_DVASPECT を返す必要があります。

矩形が返された場合、そのアスペクトに対して IViewObject::Draw を呼び出すことで完全に覆い隠されることが保証されます。コンテナーは、背面から前面への描画パスでオブジェクトの背後に他のオブジェクトを描画する前に、この矩形を使用してオブジェクトの不透明部分をクリップアウトする必要があります。非矩形の不透明領域を持つオブジェクトでこのメソッドが失敗した場合、コンテナーは背面から前面へのパスで DVASPECT_CONTENT アスペクトを使用してオブジェクト全体を描画する必要があります。

DVASPECT_TRANSPARENT オブジェクトは、すべての透明部分または不規則な部分を覆う矩形を返す必要があります。オブジェクトに透明部分や不規則な部分がない場合は、DV_E_ASPECT を返すことができます。コンテナーはこの矩形を使用して、あるオブジェクトの透明部分に重なる他のオブジェクトが存在するかどうかを判断できます。
vtbl 11 HRESULT GetViewStatus(DWORD* pdwStatus)

オブジェクトの不透明性に関する情報と、サポートされる描画アスペクトを取得します。

pdwStatusDWORD*outビューステータスへのポインター。この情報は VIEWSTATUS 列挙値の組み合わせとして返されます。

戻り値

成功した場合、このメソッドは S_OK を返します。

解説(Remarks)

描画処理を最適化するために、コンテナーはオブジェクトが不透明かどうか、および単色の背景を持つかどうかを判断できる必要があります。完全に不透明なオブジェクトによって全体が覆われているオブジェクトを再描画する必要はありません。スクロールなどの他の操作も、オブジェクトが不透明で単色の背景を持つ場合には大幅に最適化できます。

IViewObjectEx::GetViewStatus メソッドは、オブジェクトが完全に不透明かどうか(VIEWSTATUS_OPAQUE ビット)、およびその背景が単色かどうか(VIEWSTATUS_SOLIDBKGND ビット)を返します。この情報は時間とともに変化する可能性があります。オブジェクトはある時点では不透明であっても、後に、たとえば BackStyle プロパティの変更によって、全体的または部分的に透明になることがあります。オブジェクトが変化したときは、IAdviseSinkEx::OnViewStatusChange を使用してサイトに通知し、サイトがこの情報を高速アクセスのためにキャッシュできるようにする必要があります。

IViewObjectEx をサポートしないオブジェクトは、常に透明であるとみなされます。

IViewObjectEx::GetViewStatus メソッドは、どのアスペクトがサポートされているかを示すビットの組み合わせも返します。

特定の描画アスペクトがサポートされていない場合、描画アスペクトを入力パラメーターとして受け取るすべての IViewObjectEx メソッドは失敗し、E_INVALIDARG を返す必要があります。IViewObjectEx::GetViewStatus メソッドを使用すると、コンテナーはすべての描画アスペクトに関する情報を 1 回の高速な呼び出しで取得できます。通常、サポートされる描画アスペクトのセットは時間とともに変化すべきではありません。ただし、変化する場合には、オブジェクトは IAdviseSinkEx::OnViewStatusChange を使用してコンテナーに通知する必要があります。

どの描画アスペクトがサポートされているかは、オブジェクトが不透明か、部分的に透明か、完全に透明かとは独立しています。特に、DVASPECT_TRANSPARENT をサポートしない透明なオブジェクトは、背面から前面へのパスで DVASPECT_CONTENT を使用して正しく描画される必要があります。ただし、これはより多くのちらつきを生じさせる可能性があります。

vtbl 12 HRESULT QueryHitPoint(DWORD dwAspect, RECT* pRectBounds, POINT ptlLoc, INT lCloseHint, DWORD* pHitResult)

ある点がオブジェクトの指定された描画アスペクト内にあるかどうかを示します。

dwAspectDWORDin要求された描画アスペクト。
pRectBoundsRECT*in含んでいるウィンドウのクライアント座標におけるオブジェクトのバウンディング矩形。この矩形はコンテナーによって計算されて渡され、オブジェクトがヒット位置を意味のある形で解釈できるようにします。
ptlLocPOINTin含んでいるウィンドウのクライアント座標におけるヒット位置。
lCloseHintINTinコンテナーが「近い」とみなす距離(HIMETRIC 単位)。この値はヒントであり、オブジェクトは独自の方法で解釈できます。オブジェクトはこのヒントを使用して出力解像度をおおまかに推測し、ヒットテスト実装の許容範囲(expansiveness)を選択することもできます。
pHitResultDWORD*outHITRESULT 列挙値として表される、ヒットに関する情報を返すためのポインター。

戻り値

成功した場合、このメソッドは S_OK を返します。その他に返される可能性のある値には次のものがあります。

戻り値 説明
E_FAIL
このメソッドは要求されたアスペクトに対して実装されていません。代わりに DVASPECT_CONTENT を使用してください。

解説(Remarks)

非矩形オブジェクトのヒット検出をサポートするには、コンテナーが、指定された位置がオブジェクトの描画アスペクトのいずれかの内側にあるかどうかをオブジェクトに問い合わせる信頼できる方法を必要とします。この機能は IViewObjectEx::QueryHitPoint によって提供されます。

メモ このメソッドは IViewObjectEx インターフェースの一部であるため、コンテナーは必ずしもサーバーを起動することなく、マウスのヒットがオブジェクト上にあるかどうかを判断できます。ヒットがたまたまオブジェクトの内側にあった場合、そのオブジェクトはインプレースアクティブ化され、サーバーが起動される可能性が高くなります。
通常、コンテナーはまず、指定された位置がオブジェクトの矩形範囲内にあるかどうかを素早く判断します。位置がオブジェクトの矩形範囲内にある場合、コンテナーは IViewObjectEx::QueryHitPoint を呼び出して、その位置が実際にオブジェクトの内側にあることの確認を得ます。ヒット位置はコンテナーウィンドウのクライアント座標で渡されます。このメソッドが呼び出されるときオブジェクトは非アクティブである可能性があるため、 IPointerInactive::OnInactiveSetCursor の場合と同様に、同じ座標系におけるオブジェクトのバウンディング矩形もこのメソッドに渡されます。

返される可能性のある値には次のものがあります。

IViewObjectEx::QueryHitPoint は、呼び出されたオブジェクトのサブオブジェクトについては考慮しません。単に、マウスのヒットがオブジェクト内にあったかどうかを示すだけです。

IViewObjectEx::QueryHitPoint は、オブジェクトがサポートする任意の描画アスペクトに対して呼び出すことができます。要求された描画アスペクトに対してサポートされていない場合は失敗する必要があります。

透明なオブジェクトは、クリックがオブジェクト内のどこで正確に発生するかに応じて、ユーザーが透明なオブジェクトまたはその背後のオブジェクトのいずれかを選択できる複雑なヒット検出メカニズムを実装したい場合があります。 たとえば、十分に大きなテキストを表示している透明なテキストボックスでは、ユーザーが文字の間をクリックしたときに、背後のオブジェクト(たとえばビットマップ)を選択できるようにすることがあります。このため、 IViewObjectEx::QueryHitPoint が返す情報には、ヒットが不透明領域で発生したか透明領域で発生したかの指示が含まれます。

非矩形かつ透明なヒット検出の例として、背後にオブジェクト(以下の例では線)がある透明な円コントロールがあります。

:::image type="content" source="./images/a7c7fe0d-f171-4823-ba4c-b51cb90d8733.png" border="false" alt-text="対角線が引かれた円の図。円の内側と外側、および線の近くの領域についてのヒット検出値を示している。":::

表示されている値は円に対するヒットテストの結果です。灰色の領域はコントロールの一部ではありませんが、画像の周囲の「近い」とみなされる領域を示すためにここに表示されています。各オブジェクトは独自の「近い」の定義を実装しますが、コンテナーが提供するヒントによって支援されるため、画像を拡大または縮小するにつれて近さを調整できます。

上の図では、Hit、Close、Transparent とマークされた点は、Transparent とマークされたもの(ただし線に対しては close)を除いて、すべて円に対する強さの異なるヒットになります。これはヒットの強さの違いによる効果を示しています。円は transparent で応答し、線は close を主張し、transparent は close より弱いため、線がヒットを取得します。

実装者向けの注意事項

IViewObjectEx をサポートするオブジェクトは、少なくとも DVASPECT_CONTENT アスペクトに対してこのメソッドを実装する必要があります。オブジェクトは、このメソッドに応答して情報を返す以外の動作を行うべきではなく、副作用があってはなりません。
vtbl 13 HRESULT QueryHitRect(DWORD dwAspect, RECT* pRectBounds, RECT* pRectLoc, INT lCloseHint, DWORD* pHitResult)

矩形内のいずれかの点がオブジェクトの指定された描画アスペクト内にあるかどうかを示します。

dwAspectDWORDin要求された描画アスペクト。
pRectBoundsRECT*in含んでいるウィンドウのクライアント座標におけるオブジェクトのバウンディング矩形。この矩形はコンテナーによって計算されて渡され、オブジェクトがヒット位置を意味のある形で解釈できるようにします。
pRectLocRECT*inヒットテスト矩形。オブジェクトの左上隅からの相対位置で、HIMETRIC 単位で指定されます。
lCloseHintINTinコンテナーが「近い」とみなす距離(HIMETRIC 単位)。この値はヒントであり、オブジェクトは独自の方法で解釈できます。オブジェクトはこのヒントを使用して出力解像度をおおまかに推測し、ヒットテスト実装の許容範囲(expansiveness)を選択することもできます。
pHitResultDWORD*outHITRESULT 列挙値として表される、ヒットに関する情報を返すためのポインター。

戻り値

成功した場合、このメソッドは S_OK を返します。その他に返される可能性のある値には次のものがあります。

戻り値 説明
E_FAIL
このメソッドは要求されたアスペクトに対して実装されていません。代わりに DVASPECT_CONTENT を使用してください。

解説(Remarks)

コンテナーは、あるオブジェクトが別のオブジェクトの指定された描画アスペクトに重なるかどうかをテストする必要がある場合があります。対象のアスペクトのリージョン、または少なくともバウンディング矩形を要求することで、オブジェクトが重なるかどうかを判断できます。ただし、これをより素早く行う方法は、IViewObjectEx::QueryHitRect を呼び出して、指定された矩形がオブジェクトの描画アスペクトのいずれかと交差するかどうかをオブジェクトに問い合わせることです。

メモ IViewObjectEx::QueryHitPoint とは異なり、このメソッドは HITRESULT_TRANSPARENTHITRESULT_CLOSE を返しません。厳密にヒットかミスかのみであり、矩形内のどの点もヒットしない場合は HITRESULT_OUTSIDE を、矩形内の少なくとも 1 点がヒットする場合は HITRESULT_HIT を返します。

実装者向けの注意事項

IViewObjectEx をサポートするオブジェクトは、少なくとも DVASPECT_CONTENT アスペクトに対してこのメソッドを実装する必要があります。オブジェクトは、このメソッドに応答して情報を返す以外の動作を行うべきではなく、副作用があってはなりません。座標が正確に変換されないなどの理由により、ある点がヒットかどうかにあいまいさがある場合、オブジェクトは矩形内のいずれかの点がオブジェクトへのヒットである可能性があるときは常に HITRESULT_HIT を返す必要があります。すなわち、実際にはレンダリングされていない点についてヒットを主張することは許容されますが、オブジェクトのレンダリングされた画像内にあるいずれの点についてもミスを主張することは決して正しくありません。
vtbl 14 HRESULT GetNaturalExtent(DVASPECT dwAspect, INT lindex, DVTARGETDEVICE* ptd, HDC hicTargetDev, DVEXTENTINFO* pExtentInfo, SIZE* pSizel)

ユーザーがオブジェクトのサイズを変更する際にオブジェクトが使用するための、コンテナーからのサイズ変更ヒントを提供します。

dwAspectDVASPECTin

要求された描画アスペクト。DVASPECT 列挙で定義される、次のいずれかの値を指定できます。

意味
DVASPECT_CONTENT
コントロールをコンテナー内に埋め込みオブジェクトとして表示できるように、その表現を提供します。この値は通常、複合ドキュメントオブジェクトに対して指定されます。表現は画面用またはプリンター用に提供できます。
DVASPECT_DOCPRINT
ファイルメニューの印刷コマンドを使用してプリンターに印刷したかのように、コントロールの表現を画面上に提供します。記述されるデータは一連のページを表すことがあります。
DVASPECT_ICON
コントロールのアイコン表現を提供します。
DVASPECT_THUMBNAIL
ブラウジングツールで表示できるように、オブジェクトのサムネイル表現を提供します。サムネイルはおよそ 120 × 120 ピクセル、16 色(推奨)のデバイス非依存ビットマップで、場合によってはメタファイルにラップされます。
lindexINTin描画操作で対象となるオブジェクトの部分を示します。その解釈は dwAspect パラメーターの値に応じて異なります。詳細については DVASPECT 列挙を参照してください。
ptdDVTARGETDEVICE*inオブジェクトのレンダリング先となるデバイスを記述するターゲットデバイス構造体へのポインター。NULL の場合、ビューは既定のターゲットデバイス(通常はディスプレイ)用にレンダリングされます。NULL 以外の値は hicTargetDev および hdcDraw と組み合わせて解釈されます。たとえば、hdcDraw がデバイスコンテキストとしてプリンターを指定している場合、ptd パラメーターはそのプリンターデバイスを記述する構造体を指します。hicTargetDev が有効な値であれば実際にデータが印刷される場合があり、hicTargetDevNULL であれば印刷プレビューモードで表示される場合があります。
hicTargetDevHDCinptd パラメーターで示されるターゲットデバイスの情報コンテキストを指定します。オブジェクトはこれを使用してデバイスメトリクスを抽出し、デバイスの機能をテストできます。ptdNULL の場合、オブジェクトは hicTargetDev パラメーターの値を無視する必要があります。
pExtentInfoDVEXTENTINFO*inサイズ変更データを指定する DVEXTENTINFO 構造体へのポインター。
pSizelSIZE*outオブジェクトによって返されるサイズ変更データへのポインター。返されるサイズ変更データは、調整されなかった次元については -1 に設定されます。つまり、cx が -1 の場合は幅が調整されなかったことを、cy が -1 の場合は高さが調整されなかったことを意味します。サイズが調整されなかったことを示す E_FAIL が返された場合、pSizelNULL になることがあります。

戻り値

成功した場合、このメソッドは S_OK を返します。その他に返される可能性のある値には次のものがあります。

戻り値 説明
E_FAIL
このメソッドは指定された dwAspect に対して実装されていないか、サイズが調整されませんでした。
E_NOTIMPL
このメソッドは実装されていませんでした。

解説(Remarks)

コントロールのサイズ変更には、大きく分けて 2 つのアプローチがあります。第 1 のアプローチはコントロール自身にサイズ変更の責任を持たせ、第 2 のアプローチはコンテナーにコントロールのサイズ変更の責任を持たせます。第 1 のアプローチはオートサイジング(autosizing)と呼ばれます。第 2 のアプローチには 2 つの方法があります。コンテンツサイジング(content sizing)とインテグラルサイジング(integral sizing)です。

IViewObjectEx::GetNaturalExtent メソッドはコンテンツサイジングとインテグラルサイジングの両方をサポートします。コンテンツサイジングでは、コンテナーが DVEXTENTINFO 構造体をオブジェクトに渡し、オブジェクトはそこに推奨サイズを返します。インテグラルサイジングでは、コンテナーが優先サイズを DVEXTENTINFO でオブジェクトに渡し、オブジェクトが実際にその高さを調整します。インテグラルサイジングは、ユーザーがデザインモードでラバーバンド操作により新しいサイズを指定するときに使用されます。

オートサイジングは通常、Label コントロールのようなオブジェクトで発生し、autosize プロパティが有効になっていて関連付けられたテキストが変更された場合にサイズが変更されます。オートサイジングはオブジェクトの状態に応じて異なる方法で処理されます。

オブジェクトが非アクティブな場合、次のことが行われます。

  1. オブジェクトが IOleClientSite::RequestNewObjectLayout を呼び出します。
  2. コンテナーが IOleObject::GetExtent を呼び出して新しい範囲(extent)を取得します。
  3. コンテナーが IOleObject::SetExtent を呼び出して新しい範囲を調整します。
オブジェクトがアクティブな場合、次のことが行われます。
  1. オブジェクトが IOleInPlaceSite::OnPosRectChange を呼び出して、サイズ変更が必要であることを指定します。
  2. コンテナーが IOleInPlaceObject::SetObjectRects を呼び出して新しいサイズを指定します。
出典・ライセンス: 上記「公式ドキュメント」の内容は Microsoft の Win32 API ドキュメント(MicrosoftDocs/sdk-api)を日本語に翻訳・改変したものです。© Microsoft Corporation. CC BY 4.0 で提供。
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)

HSP用 COM定義

#usecom / #comfunc によるHSPのCOM呼び出し定義。数字は vtbl インデックス(0始まり)。クラスIDが無い場合 #usecom の末尾は "{}"、ある場合は "{CLSID}"

出力引数:
#define global IID_IViewObjectEx "{3AF24292-0C96-11CE-A0CF-00AA00600AB8}"
#usecom global IViewObjectEx IID_IViewObjectEx "{}"
#comfunc global IViewObjectEx_GetRect           10 int,var
#comfunc global IViewObjectEx_GetViewStatus     11 var
#comfunc global IViewObjectEx_QueryHitPoint     12 int,var,int,int,var
#comfunc global IViewObjectEx_QueryHitRect      13 int,var,var,int,var
#comfunc global IViewObjectEx_GetNaturalExtent  14 int,int,var,sptr,var,var
; ※数字は vtbl インデックス(0始まり)。0/1/2 は IUnknown(QueryInterface/AddRef/Release)。
; ※このインターフェースは直接 CoCreateInstance するクラスIDが無いため "{}"(他メソッド/アクティベーションで取得)。
; ※出力/バッファ引数は var(変数直渡し)。varptr 方式にも切替可。
; ※ハンドル/void*等の不透明ポインタは IronHSP では intptr 指定が可能。