インターフェイスがない場合の正常な機能低下
コントロールは IUnknown 以外のインターフェイスをサポートしていない可能性があるため、コンテナーは、特定のインターフェイスが存在しない場合に適切に低下する必要があります。
IUnknown以外の何も持たないコントロールの有用性を疑問に思うかもしれません。 ただし、コンテナーがオブジェクトをコントロールとして認識する場合に、コンテナーのビジュアル プログラミング環境 (VB など) からコントロールが受け取る利点を考慮してください。
- オブジェクトのボタンがツールボックスに表示されます。
- ツールボックスからフォームにドラッグすることで、オブジェクトを作成できます。
- ビジュアル プログラミング環境で認識される名前をオブジェクトに付けることができます。
- 上記 (3) の同じ名前は、同じフォーム (または別のフォーム) 上のコントロールの他のコードを記述する際にすぐに使用できます。
- コンテナーは、そのオブジェクトから使用可能なすべてのイベントのコード エントリ ポイントを自動的に提供できます。
- コンテナーには、使用可能なプロパティに対して独自のプロパティ参照 UI が用意されています。
オブジェクトがコントロールとして認識されない場合、これらの非常に強力で有益な統合機能がすべて失われる可能性があります。 たとえば、Visual Basic 4.0 では、完全な意味ではコントロールではないが、プロパティとイベントが残っている可能性があるランダム なオブジェクトを実際に統合することは非常に困難です。 Visual Basic 4 のコントロールの概念は非常に制限的であるため、オブジェクトは上記の統合機能を取得しません。 ただし、コントロールの 有効期間によってリソースの存在が決まる IUnknown のコントロールであっても、上記の統合機能を取得できる必要があります。
現在のツールでは、利点を得るために多数のコントロール インターフェイスが必要であるため、コントロールは通常、実際に必要以上のコードが含まれるように、過剰な実装に導かれています。 7K になる可能性があるコントロールは、最終的に 25K になる可能性があります。これは、インターネットなどの領域で大きなパフォーマンスの問題になります。 これは、すべてのインターフェイスを実装する複雑さのために CDK のような 1 つのツールしかコントロールを実装できないという認識にもつながり、このようなコントロールにOC30.DLLのような大きな DLL が必要な場合に、ワーキング セットが増加するという影響があります。 すべてのインターフェイスが必要でない場合は、これにより、多数の開発者が、単純な OLE や他のツールを使用して非常に小さく軽いコントロールを作成し、各コントロールのオーバーヘッドを最小限に抑えることができます。
このため、この付録では、CLSID と IUnknown インターフェイスを持つ任意のオブジェクトとしてコントロールを認識します。 IUnknown 以外の機能がなくても、プログラミング環境を持つコンテナーは、少なくとも機能 #3 と ) レジストリ エントリを提供できる必要があり、#1 と #2 が得られます。 オブジェクトが一部のイベント セットに IConnectionPointContainer (および IProvideClassInfo) を提供すると、#5 が取得され、プロパティとメソッドに対して IDispatch がサポートされている場合は、#6 が得られ、コンテナーでのコード統合も向上します。
要するに、オブジェクトは IDispatch と IConnectionPointContainer を介して公開される 1 つのイベント セットを実装して、上記のすべてのビジュアル機能を取得できる必要があります。
これを念頭に置いて、次の表では、可能なインターフェイスがない場合のコンテナーの動作について説明します。 コンテナーが QueryInterface を介して直接取得するインターフェイスのみが一覧表示されることに注意してください。 IOleInPlaceActiveObject などの他のインターフェイスは、他の方法で取得されます。
インターフェイス | インターフェイスの不在の意味 |
---|---|
IViewObject2 |
コントロールにはそれ自体を描画するビジュアルがないため、提供する明確なエクステントはありません。 実行時に、このインターフェイスが存在しない場合、コンテナーは何も描画しません。 デザイン時には、コンテナーは少なくとも、このようなコントロールの名前を持つ何らかの既定の四角形を描画する必要があります。そのため、ビジュアル プログラミング環境のユーザーはオブジェクトを選択し、存在するプロパティ、メソッド、およびイベントをチェックできます。 IViewObject2 が存在しない場合の処理は、優れたビジュアル プログラミングのサポートに不可欠です。 |
IOleObject |
コントロールはサイトを必要とせず、埋め込みオブジェクト レイアウト ネゴシエーションにも参加しません。 コンテナーがこのインターフェイスから予期する可能性がある情報 (制御エクステントなど) には、コンテナーによって提供される既定値を入力する必要があります。 |
IOleInPlaceObject |
コントロールは(ラベルのように) インプレースアクティブになりません。そのため、この方法でアクティブ化を試みることはありません。 その唯一のアクティブ化は、そのプロパティ ページである可能性があります。 |
IOleControl |
コントロールにはニーモニックがなく、アンビエント プロパティは使用されません。コンテナーがイベントを無視するかどうかは気にしません。 このインターフェイスがない場合、コンテナーはそのメソッドを呼び出しません。 |
Idataobject |
このコントロールには、キャッシュ可能なプロパティ セットもビジュアル レンダリングも提供されないため、コンテナーは、このインターフェイスがない場合に既定のプレゼンテーションをキャッシュし (特にCF_METAFILEPICTのサポート)、プロパティ セット関連の機能を無効にすることを選択します。 |
IDispatch |
コントロールにカスタム プロパティまたはメソッドがありません。 この場合、コンテナーはコントロールプロパティを表示する必要はありません。また、コンテナーが独自の拡張コントロールに属していると認識しないカスタム メソッド呼び出しを禁止する必要があります (メソッドとプロパティをサポートしている可能性があります)。 拡張コントロールは通常、特定 の IDispatch 呼び出しをコントロールに委任するため、拡張コントロールでは、コントロール に IDispatch がまったく含まれるとは想定しないでください。 |
IConnectionPointContainer |
コントロールにはイベントがないため、コンテナーは処理について考慮する必要はありません。 |
IProvideClassInfo IProvideClassInfo2 |
コントロールに型情報またはイベントがないか、コンテナーがコントロールのレジストリ エントリを介してコントロールの型情報に入る必要があります。 このインターフェイスの存在は最適化です。 |
ISpecifyPropertyPages |
コントロールにはプロパティ ページがないため、コンテナーに呼び出す UI がある場合、コンテナーはその UI を無効にする必要があります。 |
IPerPropertyBrowsing |
コントロールには、表示名自体、事前に定義された文字列と値、およびページマッピングに対するプロパティがありません。 このインターフェイスは、コンテナー ユーザー インターフェイスの生成にほぼ常に使用されるため、このインターフェイスがない場合は、このような UI 要素が無効になります。 |
IPersist* |
コントロールには永続的な状態がないため、コンテナーはコントロール固有のデータの保存について心配する必要はありません。 もちろん、コンテナーはコントロールに関する独自の情報を独自の形式またはドキュメントで保存しますが、コントロール自体はその情報に影響を与えることはありません。 |
IOleCache IOleCache2 |
オブジェクトはキャッシュをサポートしていません。 コンテナーでは、CreateDataCache を使用してデータ キャッシュ自体を作成するだけで、キャッシュを引き続きサポートできます。 |