Share via


ウィンドウなしのアクティベーション

ウィンドウ作成コード (CreateWindow を呼び出すときに発生するすべてのコード) の実行にはコストがかかります。 画面上のウィンドウを保持するコントロールは、そのウィンドウのメッセージを管理する必要があります。 このため、ウィンドウなしのコントロールは、ウィンドウを含むコントロールよりも高速です。

さらに、ウィンドウなしのコントロールは、ウィンドウ付きコントロールとは異なり、透明な描画と四角形以外の画面領域をサポートしています。これはウィンドウなしのコントロールの利点です。 透明なコントロールの例として一般的なのが、背景が透明なテキスト コントロールです。 このコントロールはテキストを描画しますが、背景は描画しません。このため、テキストの下にあるものはすべて表示されます。 さらに新しいフォームでは、矢印や丸いボタンなど、四角形以外のコントロールがよく使用されます。

多くの場合、コントロールは独自のウィンドウを必要としません。代わりに、そのコンテナーのウィンドウ サービスを使用できます (コンテナーがウィンドウなしのオブジェクトをサポートするように記述されている場合)。 ウィンドウなしのコントロールは、古いコンテナーとの下位互換性があります。 ウィンドウなしのコントロールをサポートするように記述されていない古いコンテナーで、ウィンドウなしのコントロールがアクティブになると、ウィンドウが作成されます。

ウィンドウなしのコントロールには独自のウィンドウがないため、(ウィンドウがある) コンテナーは、そのコントロールの独自のウィンドウで提供されるはずのサービスを提供しなければなりません。 たとえば、コントロールでキーボードのフォーカスにクエリを実行したり、マウスをキャプチャしたり、デバイスのコンテキストを取得したりする必要がある場合、これらの操作はコンテナーによって管理されます。 コンテナーは、そのウィンドウに送信されたユーザー入力メッセージを、IOleInPlaceObjectWindowless インターフェイスを使用して、適切なウィンドウなしのコントロールにルーティングします (〘 このインターフェイスの説明については、ActiveX SDK を参照してください)。) COleControl メンバー関数は、コンテナーからこれらのサービスを呼び出します。

ご自身のコントロールでウィンドウなしのアクティベーションを使用するには、COleControl::GetControlFlags によって返されるフラグのセットに windowlessActivate フラグを含めます。 次に例を示します。

DWORD CMyAxOptCtrl::GetControlFlags()
{
   DWORD dwFlags = COleControl::GetControlFlags();
// The control can activate without creating a window.
dwFlags |= windowlessActivate;
return dwFlags;
}

このフラグを含めるコードは、MFC ActiveX コントロール ウィザードの [Control Settings]\(コントロールの設定\) ページで [Windowless activation]\(ウィンドウなしのアクティベーション\) オプションを選択すると、自動的に生成されます。

ウィンドウなしのアクティベーションが有効になっている場合、コンテナーは入力メッセージをコントロールの IOleInPlaceObjectWindowless インターフェイスにデリゲートします。 COleControl では、このインターフェイスを実装することにより、マウスの座標を適切に調整した後、ご自身のコントロールのメッセージ マップを通じてメッセージをディスパッチします。 通常のウィンドウ メッセージのようにメッセージを処理するには、対応するエントリを、メッセージ マップに追加します。 これらのメッセージのハンドラーでは、m_hWnd メンバー変数 (またはそれを使用するメンバー関数) を、最初にその値が NULL でないことを確認せずに使用することは避けてください。

COleControl には、マウス キャプチャ、キーボード フォーカス、スクロールなどのウィンドウ サービスをコンテナーから適宜呼び出すメンバー関数が用意されています。

ウィンドウなしのコントロールでは常に、COleControl メンバー関数を使用する必要があります。対応する CWnd メンバー関数やその関連する Win32 API 関数を使用するのではありません。

ウィンドウなしのコントロールを、OLE ドラッグ アンド ドロップ操作のターゲットにすることができます。 通常、これを行うには、コントロールのウィンドウがドロップ先として登録されている必要があります。 コントロールには独自のウィンドウがないため、コンテナーは、その独自のウィンドウをドロップ先として使用します。 コントロールは、コンテナーが適切なタイミングで呼び出しをデリゲートできる IDropTarget インターフェイスの実装を提供します。 このインターフェイスをコンテナーに公開するには、COleControl::GetWindowlessDropTarget をオーバーライドします。 次に例を示します。

IDropTarget* CMyAxOptCtrl::GetWindowlessDropTarget()
{
   m_DropTarget.m_xDropTarget.AddRef();
   return &m_DropTarget.m_xDropTarget;
}

関連項目

MFC ActiveX コントロール: 最適化