TN062: Windows コントロール メッセージ リフレクション

このテクニカル ノートでは、メッセージ リフレクション、MFC 4.0 の新機能について説明します。メッセージ リフレクションを使用して、単純な再利用可能なコントロールを作成する方法についても含まれます。

(以前は OLE コントロールと呼ばれて) ActiveX コントロールに適用されるこのテクニカル ノート メッセージ リフレクションのについては説明しません。記事を参照してください ActiveX コントロール: Windows コントロールをサブクラス化 Visual の C++ プログラマのガイド

メッセージ リフレクションは何です。?

Windows コントロールは頻繁にその親ウィンドウに通知メッセージを送信します。たとえば、多くのコントロールを親コントロールの背景を描画するブラシを供給するように親コントロール カラー通知メッセージ (WM_CTLCOLORまたはそのバリエーションの 1 つ) を送信します。

Windows および MFC バージョン 4.0 では、親ウィンドウ、ダイアログ ボックスでは多くの場合、これらのメッセージを処理するための責任です。つまり、メッセージを処理するコードが、親ウィンドウのクラスにする必要があると、そのメッセージを処理する必要があるすべてのクラスで複製しています。上記のケースでは、カスタムの背景をコントロールしたいすべてのダイアログ ボックス コントロール カラー通知メッセージを処理する必要があります。コントロール クラスは独自の背景色を処理する書き込まれる可能性がある場合にコードを再利用しやすくなります。

MFC 4.0 では、古いメカニズムをまだ働きます ? 親ウィンドウは、通知メッセージを処理することができます。さらに、ただし、MFC 4.0 の再利用「メッセージ リフレクション」と呼ばれる機能を提供することによって促進できる子コントロール ウィンドウまたは親ウィンドウのいずれかまたは両方を処理するこれらの通知メッセージ。コントロールの背景色の例では、今反射のWM_CTLCOLORメッセージを処理することによって、独自の背景色を設定、コントロール クラスを記述することができます ? 親に依存することがなく。(メッセージ リフレクションが MFC で実装されているため、Windows では、親ウィンドウ クラスするCWndからメッセージ リフレクションを派生する必要がありますいないことに注意してください)。

以前のバージョンの MFC メッセージ リフレクションに似たメッセージ (WM_DRAWITEMなどのオーナー描画リスト ボックスなどのいくつかのメッセージの仮想機能を提供することでしました。新しいメッセージ リフレクション機構を一般化され、一貫しました。

メッセージ リフレクションの MFC のバージョン 4.0 の前に書かれたコードとの下位互換性です。

独自のハンドラーの基本クラスのハンドラー関数を呼び出さない限り、特定のメッセージのハンドラーを指定したメッセージを親ウィンドウのクラスの範囲をオーバーライドする場合、同じメッセージのメッセージ ハンドラーを反映しました。ダイアログ ボックス クラスでWM_CTLCOLORを処理する場合、たとえば、あなたの処理が、リフレクション メッセージ ハンドラーをオーバーライドします。

親ウィンドウ クラスで、ハンドラーを特定のWM_NOTIFYメッセージまたはWM_NOTIFYメッセージの範囲を指定した場合は、それらのメッセージを送信する子コントロールON_NOTIFY_REFLECT()を通じてリフレクション メッセージ ハンドラーがあるない場合にのみ、ハンドラーが呼び出されます。メッセージ マップにON_NOTIFY_REFLECT_EX()を使用する場合は、メッセージ ハンドラーがあります。 または、メッセージを処理するために、親ウィンドウができない場合があります。ハンドラーがTRUEを返す場合は、メッセージ、親も、 FALSEそれを処理する、親はできませんを返しますを呼び出し中取り扱われます。リフレクション メッセージ、通知メッセージの前に処理されることに注意してください。

WM_NOTIFYメッセージが送信されると、コントロールはそれを処理するには、最初の機会が提供されます。他のリフレクション メッセージが送信された場合は、親ウィンドウにそれを処理するには、最初のチャンスが、コントロールはリフレクション メッセージが表示されます。これを行うには、ハンドラー関数および適切なコントロールのクラスのメッセージ マップ エントリ必要。

リフレクション メッセージのメッセージ マップ マクロは正規の通知のよりもわずかに異なるです: それは、通常の名前に_REFLECTが追加。たとえば、親のWM_NOTIFYメッセージを処理するには、親のメッセージ マップにON_NOTIFYマクロを使用します。子コントロールにリフレクション メッセージを処理するには、子コントロールのメッセージ マップにON_NOTIFY_REFLECTマクロを使用します。いくつかのケースでは、パラメーターにも異なっています。ClassWizard が、通常メッセージ マップ エントリを追加してスケルトン関数の実装で適切なパラメーターを提供することに注意してください。

参照してくださいTN061: ON_NOTIFY と WM_NOTIFY メッセージ新しいWM_NOTIFYメッセージについて。

メッセージ マップ エントリとリフレクション メッセージ ハンドラー関数プロトタイプ

反射のコントロール通知メッセージを処理するには、メッセージ マップ マクロと関数のプロトタイプでは、次の表を使用します。

ClassWizard は通常これらのメッセージ マップ エントリを追加し、スケルトン関数の実装を提供できます。参照してください ハンドラーを定義する方法についてのVisual の C++ プログラマのガイドリフレクション メッセージのメッセージ ハンドラーの定義

メッセージ名を反射のマクロ名に変換するには、 _reflectし、されました。たとえば、 WM_CTLCOLOR ON_WM_CTLCOLOR_REFLECTになります。(メッセージを反映することができますを参照するには、次の表のマクロ エントリを逆変換をしないでください)。

上記の規則に 3 つの例外は次のとおりです。:

各上記の特殊なケースでは、ハンドラーのメンバー関数の名前を指定する必要があります。その他の例では、ハンドラー関数の標準的な名前を使用する必要があります。

パラメーターの意味と、関数の戻り値は関数名または関数名で付加で記載されています。たとえば、 CtlColorでのOnCtlColor記載されています。いくつかのリフレクション メッセージ ハンドラーでは、親ウィンドウ内の同様のハンドラーよりも少ないパラメーター必要があります。ちょうど以下の表の名前、ドキュメント内の仮パラメーターの名前と一致します。

マップ エントリ 関数プロトタイプ
ON_CONTROL_REFLECT ( wNotifyCode, memberFxn afx_msg voidmemberFxn ( );
ON_NOTIFY_REFLECT ( wNotifyCode, memberFxn afx_msg voidmemberFxn(NMHDR ※ pNotifyStructLRESULT ※ 結果 );
ON_UPDATE_COMMAND_UI_REFLECT ( memberFxn afx_msg voidmemberFxn(CCmdUI ※ pCmdUI );
ON_WM_CTLCOLOR_REFLECT) afx_msg HBRUSH CtlColor (CDC ※ pDC、UINT nCtlColor );
ON_WM_DRAWITEM_REFLECT) afx_msg 無効 DrawItem (LPDRAWITEMSTRUCT lpDrawItemStruct );
ON_WM_MEASUREITEM_REFLECT) afx_msg 無効 MeasureItem (LPMEASUREITEMSTRUCT lpMeasureItemStruct );
ON_WM_DELETEITEM_REFLECT) afx_msg 無効 DeleteItem (LPDELETEITEMSTRUCT lpDeleteItemStruct );
ON_WM_COMPAREITEM_REFLECT) afx_msg int CompareItem (LPCOMPAREITEMSTRUCT lpCompareItemStruct );
ON_WM_CHARTOITEM_REFLECT) afx_msg int CharToItem (UINT が nKey、UINT nIndex );
ON_WM_VKEYTOITEM_REFLECT) afx_msg int VKeyToItem (UINT が nKey、UINT nIndex );
ON_WM_HSCROLL_REFLECT) afx_msg 無効 HScroll (UINT nSBCode、UINT Npo );
ON_WM_VSCROLL_REFLECT) afx_msg 無効 VScroll (UINT nSBCode、UINT Npo );
ON_WM_PARENTNOTIFY_REFLECT) afx_msg void ParentNotify (UINT メッセージ、LPARAM lParam );

ON_NOTIFY_REFLECTON_CONTROL_REFLECTのマクロがある 1 つ以上のオブジェクト (コントロールとその親) など、特定のメッセージを処理することができますバリエーション。

マップ エントリ 関数プロトタイプ
ON_NOTIFY_REFLECT_EX ( wNotifyCode, memberFxn afx_msg BOOLmemberFxn(NMHDR ※ pNotifyStructLRESULT ※ 結果 );
ON_CONTROL_REFLECT_EX ( wNotifyCode, memberFxn afx_msg BOOLmemberFxn ( );

反映済みメッセージの処理: 再利用可能なコントロールの例

この単純な例と呼ばれる再利用可能なコントロールを作成 CYellowEdit 。コントロールは通常のエディット コントロールと同じ動作が、それは黄色の背景に黒のテキストが表示されます。許可するメンバー関数を追加するは簡単だろう、 CYellowEdit 別の色を表示するコントロール。

この例を実行するには、次の手順を実行をします:

  1. 新しいダイアログ ボックスで既存のアプリケーションを作成します。詳細についてを参照してください ダイアログ エディターVisual の C++ ユーザーのガイド

    あなたがアプリケーションで再利用可能なコントロールを開発する必要があります。使用する既存のアプリケーションを持っていない場合は、AppWizard を使用してダイアログ ベースのアプリケーションを作成します。

  2. Visual C に読み込まれたプロジェクトで、ClassWizard を使用すると呼ばれる新しいクラスを作成する CYellowEdit CEditに基づきます。チェック、「コンポーネント ギャラリーに追加する」のまま。

  3. 3 つのメンバー変数を追加、 CYellowEdit クラス。最初の 2 つのテキストの色と背景色を保持するCOLORREF変数になります。3 番目は背景に描画ブラシを保持するCBrushオブジェクトになります。CBrushオブジェクトを一度、単なるその後、参照するブラシを作成して自動的にとき、ブラシを破壊することができます、 CYellowEdit コントロールが破棄されます。

  4. コンス トラクターは次のように書き込むことによって、メンバー変数を初期化します。:
    CYellowEdit::CYellowEdit(){m_clrText RGB (0, 0, 0); =m_clrBkgnd RGB (255, 255, 0); =m_brBkgnd.CreateSolidBrush (m_clrBkgnd);}
    
  5. ClassWizard を使用して追加のハンドラーを反射のWM_CTLCOLORメッセージに、 CYellowEdit クラス。あなたが処理できるメッセージの一覧で、メッセージ名の前に等号 (=)、メッセージが反映されていることを示すことに注意してください。これで記載されている Visual の C++ プログラマのガイド 、「リフレクション メッセージ用のメッセージ ハンドラーの定義

    ClassWizard は、次のメッセージ マップ マクロとスケルトン関数を追加します:

    ON_WM_CTLCOLOR_REFLECT()・ ・ メモ: その他のコードの間になります…。HBRUSH CYellowEdit::CtlColor(CDC* pDC, UINT nCtlColor) {//TODO: ここの DC の属性を変更//TODO: 場合は、NULL 以外のブラシを返します、・ ・親のハンドラーが呼び出さする必要がありますNULL を返す;}
    
  6. 関数の本体を次のコードに置き換えます。コードのテキストの色、テキストの背景色、および背景色、コントロールの残りの部分を指定します。
    pDC gt;SetTextColor (m_clrText);//テキストpDC - > SetBkColor (m_clrBkgnd);//テキストの bkgndm_brBkgnd を返す;//ctl bkgnd
    
  7. エディット コントロールをダイアログ ボックスで、作成し、それをメンバー変数に、ctrl キーを押しながら、編集コントロールをダブルクリックして接続します。メンバー変数の追加] ダイアログ ボックスで、変数名を完了し、カテゴリ、「CYellowEdit」変数の型を「コントロール」を選択します。ダイアログ ボックスで、タブ オーダーを設定することを忘れないでください。また、ヘッダー ファイルを含めるように、 CYellowEdit コントロールをダイアログ ボックスのヘッダー ファイル。

  8. ビルドして、アプリケーションを実行します。エディット コントロールが黄色の背景をが。

  9. 追加するコンポーネント ギャラリーを使用することができます、 CYellowEdit クラスに他のプロジェクトを制御。

番号順テクニカル ノート|nbsp;カテゴリ別テクニカル ノート(&N)

Index