MFC ActiveX コントロール : Windows コントロールのサブクラス化
この技術情報は、 ActiveX コントロールを作成するための共通の Windows コントロールをサブクラス化するプロセスを説明します。サブクラス化は既存のウィンドウ コントロール ActiveX コントロールを開発する最も簡単です。新しいコントロールにマウスのクリックに描画と応答のようなサブクラス化された Windows コントロールの機能があります。MFC ActiveX コントロールのサンプル ボタン は Windows コントロールをサブクラス化の例です。
サブクラスに Windows コントロールは、次のタスクを実行します:
COleControl の IsSubclassedControl と PreCreateWindow のメンバー関数をオーバーライドします。
OnDraw のメンバー関数を変更します。
コントロールに反映される ActiveX コントロールのメッセージ (OCM)を処理します
[!メモ]
この作業のほとんどは、 ActiveX コントロール ウィザードによって自動的に Control Settings のページの Select Parent Window Class のドロップダウン リストを使用してサブクラス化するコントロールを選択すると発生します。
コントロールをサブクラス化の詳細については、サポート技術情報の文書 Q243454 を参照してください。
オーバーライドの IsSubclassedControl と PreCreateWindow
PreCreateWindow と IsSubclassedControlをオーバーライドするには、コントロール クラスの宣言の protected のセクションに次のコード行を追加します:
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
BOOL IsSubclassedControl();
コントロールの実装ファイル (.cpp)では、 2 種類のオーバーライドされた関数を実行する次のコード行を追加します:
// CMyAxSubCtrl::PreCreateWindow - Modify parameters for CreateWindowEx
BOOL CMyAxSubCtrl::PreCreateWindow(CREATESTRUCT& cs)
{
cs.lpszClass = _T("BUTTON");
return COleControl::PreCreateWindow(cs);
}
// CMyAxSubCtrl::IsSubclassedControl - This is a subclassed control
BOOL CMyAxSubCtrl::IsSubclassedControl()
{
return TRUE;
}
、この例では、 Windows のボタン コントロールが PreCreateWindowに指定しています。ただし、どの標準のペインのコントロールがサブクラス化できます。標準のウィンドウ コントロールの詳細については、 コントロールを参照してください。
サブクラス化と Windows コントロール、コントロールのウィンドウの作成に使用する特定のウィンドウの**WS_**フォーム ()または拡張ウィンドウ スタイル (WS_EX_)フラグを指定する必要があります。cs.style と cs.dwExStyle の構造体フィールドの変更によって PreCreateWindow のメンバー関数のこれらのパラメーターの値を設定できます。これらのフィールドへの変更は OR 操作を使用してクラス COleControlによって設定された既定のフラグを保持するために行う必要があります。たとえば、コントロールがボタン コントロールをサブクラス化、コントロールにチェック ボックスとして表示する場合は、 return ステートメントの前に CSampleCtrl::PreCreateWindowの実装に次のコード行を挿入します:
cs.style |= BS_CHECKBOX;
この操作は、クラス COleControl の既定のスタイル フラグ (WS_CHILD)をそのまま維持されます BS_CHECKBOX のフォームのフラグを追加します。
OnDraw のメンバー関数の変更
サブクラス化されたコントロールに対応する DoSuperclassPaint のメンバー関数に Windows コントロール、コントロールの OnDraw のメンバー関数呼び出しのみ含まれているのと同じ外観を保持する場合、次の例のように:
void CMyAxSubCtrl::OnDraw(CDC* pdc, const CRect& rcBounds, const CRect& /*rcInvalid*/)
{
if (!pdc)
return;
DoSuperclassPaint(pdc, rcBounds);
}
COleControlによって実装される DoSuperclassPaint のメンバー関数は外接する四角形内の指定されたデバイス コンテキストのコントロールを描画したときに Windows のコントロールのウィンドウ プロシージャを使用します。これは、アクティブでないときでも、コントロールを表示します。
[!メモ]
DoSuperclassPaint のメンバー関数はデバイス コンテキストが WM_PAINT のメッセージの wParam として渡すことができるようにするそれらのコントロール型でのみ使用できます。これは、標準のウィンドウ コントロールの一部、 SCROLLBAR と ボタンなど、すべてのコモン コントロールが含まれます。この動作をサポートしないコントロールに対して、適切に動作しないコントロールを表示する独自のコードを提供する必要があります。
リフレクションされたウィンドウ メッセージの処理
ウィンドウ コントロールには親ウィンドウには、指定されたウィンドウ メッセージを送信します。これらのメッセージの一部は、 WM_COMMANDのようなユーザーによって、アクションを通知します。他のユーザーが、 WM_CTLCOLORなど、親ウィンドウから情報を取得するために使用します。ActiveX コントロールは、通常そのほかの方法によって親ウィンドウと通信します。通知が発生させるイベントによって (イベント通知を送信します)伝えられ、コントロール コンテナーに関する情報はコンテナーのアンビエント プロパティのアクセスになります。これらの通信の手法があるため、 ActiveX コントロール コンテナーがコントロールから送信されたウィンドウ メッセージを処理しません。
コンテナーがコントロールの親として実行するようにサブクラス化された Windows コントロールから送られたウィンドウ メッセージを受け取ることを COleControl を作成する追加のペインができないようにします。「リフレクターと呼ばれるこの追加のウィンドウがサブクラス制御するウィンドウが作成され、コントロール ペインと同じサイズと位置がある ActiveX コントロールに対して」。リフレクターのウィンドウ中継ルーチンの特定のウィンドウ メッセージは、コントロールにそれらを行って。コントロールは、ウィンドウ プロシージャで ActiveX コントロールの適切な処理を行うと、これらのリフレクション メッセージを処理できます (たとえば、イベントを発生します)。傍受したウィンドウのメッセージと対応するリフレクション メッセージの一覧については、 リフレクションされたウィンドウ メッセージ ID を参照してください。
ActiveX コントロール コンテナーはリフレクション メッセージ自体を実行するように設計されているとします。 COleControl の必要がリフレクター ペインを作成する操作を削除し、サブクラス化された Windows コントロールのランタイムのオーバーヘッドが減少します。COleControl は TRUEの値の MessageReflect のアンビエント プロパティをチェックしてかどうかをコンテナー サポートこの機能検出します。
リフレクションされたウィンドウ メッセージを処理するには、メッセージ マップ エントリをコントロールに追加し、ハンドラー関数を実行します。リフレクション メッセージは、 Windows で定義されているメッセージの標準セットの一部ではないため、クラス ビューは、そのようなメッセージ ハンドラーの追加をサポートしません。ただし、ハンドラーを手動で追加することは困難ではありません。
リフレクションされたウィンドウ メッセージのメッセージ ハンドラーを追加するには、手動で次のようにします:
コントロール クラス。H ファイルは、ハンドラー関数を宣言します。関数では、それぞれ LRESULT と 2 個のパラメーターの戻り値の型が、型 WPARAM と LPARAMである必要があります。次に例を示します。
class CMyAxSubCtrl : public COleControl { ... protected: LRESULT OnOcmCommand(WPARAM wParam, LPARAM lParam); };
コントロール クラスの .cpp ファイルでは、メッセージ マップに ON_MESSAGE エントリを追加します。このエントリのパラメーターは、ハンドラー関数のメッセージ識別子と名前を指定する必要があります。次に例を示します。
BEGIN_MESSAGE_MAP(CMyAxSubCtrl, COleControl) ON_MESSAGE(OCM_COMMAND, &CMyAxSubCtrl::OnOcmCommand) END_MESSAGE_MAP()
また、 .cpp ファイルで、リフレクション メッセージを処理するに OnOcmCommand のメンバー関数を実装します。wParam と lParam パラメーターは、元のウィンドウ メッセージと同じです。
例のためにリフレクション メッセージがどのように処理されるか、 MFC ActiveX コントロールのサンプル ボタンを参照してください。これは BN_CLICKED 通知コードを検出し、送信 ()によって起動クリック イベントに応答 OnOcmCommand ハンドラーを示します。