TN061: ON_NOTIFY と WM_NOTIFY メッセージ

このテクニカル ノートで、新しいWM_NOTIFYメッセージの背景情報を提供し、MFC アプリケーションで返送された WM_NOTIFYメッセージを処理、推奨 (最も一般的な) 方法について説明します。

Windows 3.x での通知メッセージ

Windows 3.x では、マウスのクリックなどのイベントの親コントロールに通知コンテンツ選択、およびコントロールの背景の描画に、親にメッセージを送信することによって変更します。単純な通知通知コード ( BN_CLICKED) などの特別のWM_COMMANDメッセージとして送信され、 wParamlParamで、コントロールのハンドルにパック ID を制御します。WParamlParamに満ちているので、そこはありません任意の追加データを渡す方法 ? これらのメッセージは簡単な通知をすることができます。たとえば、 BN_CLICKED通知では、ボタンがクリックしてされたとき、マウス カーソルの位置についての情報を送信する方法はありません。

Windows 3.x でコントロールを追加データを含む通知メッセージを送信する必要がある場合は、さまざまなWM_CTLCOLORWM_VSCROLLWM_HSCROLLWM_DRAWITEMために、WM_MEASUREITEM、のWM_COMPAREITEMWM_DELETEITEMWM_CHARTOITEMWM_VKEYTOITEMを含む、特別な目的のメッセージを使用、などなど。これらのメッセージは、それらを送信元のコントロールに反映することができます。詳細についてを参照してくださいTN062: メッセージ リフレクションの Windows コントロール

Win32 での通知メッセージ

Windows 3.1 で存在したコントロールでは、Win32 API は Windows 3.x で使用された通知メッセージのほとんどを使用します。ただし、Win32 も洗練された、複雑なコントロールの数はそれらに Windows 3.x。 でよくサポートを追加、これらのコントロールの通知メッセージを追加のデータを送信する必要があります。新しいwm _ ※メッセージ追加データが必要なそれぞれの新しい通知を追加することなく、が Win32 API の設計者は 1 つだけメッセージをWM_NOTIFY追加データの任意の金額は、標準化された形式で渡すことができますを追加するを選択。

WM_NOTIFYメッセージにはwParamとポインターで構造体のlParamへメッセージを送信するコントロールの ID が含まれます。この構造体は、 NMHDR構造体またはその最初のメンバーとしてNMHDR構造体を持ついくつかのより大きい構造のいずれかです。NMHDRメンバーから最初にある注意この構造体へのポインターはポインターのいずれかにするには、 NMHDRまたはキャストの方法に応じてより大きな構造体へのポインターとして使用することができます。

ほとんどの場合、ポインターより大きな構造体をポイントして、それを使用すると、それをキャストする必要があります。( NM_で始まる名前) 共通の通知と、ツール ヒント コントロールのTTN_SHOWTTN_POPの通知など、いくつかの通知だけで実際に使用されるNMHDR構造です。

NMHDR構造体または最初のメンバーには、ハンドルと、メッセージと、通知コード ( TTN_SHOW) などを送信するコントロールの ID が含まれます。NMHDR構造体の形式を以下に示します:

typedef 構造体 tagNMHDR {特価;HWND hwndFrom;UINT idFrom;UINT コード;} NMHDR(&N)

TTN_SHOWメッセージでは、コードのメンバー TTN_SHOWに設定します。

ほとんどの通知は、最初のメンバーとしてNMHDR構造体を含む大きな構造体へのポインターを渡します。たとえば、リスト ビュー コントロールでキーが押されたときに送信される、リスト ビュー コントロールのLVN_KEYDOWN通知メッセージで使用される構造を検討します。以下のように定義されている、 LV_KEYDOWN構造体へのポインターを指す:

typedef 構造体 tagLV_KEYDOWN {特価;NMHDR hdr;WORD wVKey;UINT フラグ;} LV_KEYDOWN(&N)

NMHDRメンバーがこの構造に最初は、通知メッセージに渡さしているポインター、 NMHDRへのポインターまたは、 LV_KEYDOWNへのポインターにキャストすることができます注意してください。

すべての新しい Windows コントロールに共通の通知

いくつかの通知は、すべての新しい Windows コントロールに共通です。これらの通知はNMHDR構造体へのポインターを渡す。

通知コード に送信
NM_CLICK ユーザーがコントロールでマウスの左ボタンをクリックして
NM_DBLCLK コントロールでユーザーがダブルクリック マウスの左ボタン
NM_RCLICK ユーザーがコントロールでマウスの右ボタンをクリックして
NM_RDBLCLK コントロールでユーザーがダブルクリックのマウスの右ボタン
NM_RETURN ユーザーがコントロールに入力フォーカスがあるときに ENTER キーを押す
NM_SETFOCUS コントロールが入力フォーカスをしています。
NM_KILLFOCUS コントロールが入力フォーカスを失った。
NM_OUTOFMEMORY 利用可能な十分なメモリがないので制御操作を完了できませんでした。

ON_NOTIFY: MFC アプリケーションの WM_NOTIFY メッセージを処理します。

関数CWnd::OnNotifyは、通知メッセージを処理します。既定の実装を呼び出す通知ハンドラーのメッセージ マップをチェックします。一般に、 OnNotifyをオーバーライドしません。代わりに、ハンドラー関数を提供し、そのハンドラーをオーナー ウィンドウのクラスのメッセージ マップにメッセージ マップ エントリを追加。

ClassWizard、ClassWizard のプロパティ シートまたはウィザード バー、 ON_NOTIFYメッセージ マップ エントリを作成し、スケルトン ハンドラ関数を提供できます。簡単に ClassWizard の使用方法の詳細についてを参照してください Visual の C++ プログラマのガイド関数へののメッセージのマッピング

ON_NOTIFYメッセージ マップ マクロは次の構文があります。:

ON_NOTIFY ( wNotifyCode, id, memberFxn

ここで、斜体のパラメーターに置き換えられます:

wNotifyCode

通知メッセージ、 LVN_KEYDOWNなどを処理するコード。

id

通知の送信先のコントロールの子の識別子。

memberFxn

この通知が送信されるときに呼び出されるメンバー関数。

メンバー関数は、次のプロトタイプを宣言する必要があります。:

afx_msg void memberFxn( NMHDR pNotifyStruct, LRESULT 結果 );

斜体のパラメーターが:

pNotifyStruct

上記のセクションの説明に従って、通知の構造体へのポインター。

結果

結果コードへのポインターを返す前に設定します。

場合は、メンバー関数を指定する OnKeydownList1 id CListCtrlからLVN_KEYDOWNメッセージを処理する IDC_LIST1 、ClassWizard を使用して、次のメッセージ マップに追加すると:

ON_NOTIFY (LVN_KEYDOWN、[IDC_LIST1] OnKeydownList1)

上記の例では、ClassWizard で提供される関数です。:

cMessageReflectionDlg::OnKeydownList1 (NMHDR ※ pNMHDR、LRESULT ※ pResult) が無効します。{LV_KEYDOWN ※ pLVKeyDow LV_KEYDOWN ※ pNMHDR; =//TODO: コントロール通知ハンドラーを追加//特価;ここにコード※ pResult = 0;}(&N)

ClassWizard が適切な型のポインターを自動的に提供することに注意してください。通知構造をいずれかを介してアクセスすることができます pNMHDR またはpLVKeyDow

ON_NOTIFY_RANGE

一連のコントロールを同じWM_NOTIFYメッセージを処理する必要がある場合は、 ON_NOTIFYではなくON_NOTIFY_RANGEを使用することができます。たとえば、特定の通知メッセージの同じアクションを実行するボタンのセットを必要があります。

ON_NOTIFY_RANGEを使用すると、一連の子の識別子の先頭を指定して、子の識別子の範囲の終了が通知メッセージを処理する範囲を指定します。

ClassWizard では、 ON_NOTIFY_RANGEをは処理されません。それを使用するには、自分のメッセージ マップを編集する必要があります。

メッセージ マップのエントリとON_NOTIFY_RANGEの関数プロトタイプは次のとおりです。:

ON_NOTIFY_RANGE ( wNotifyCode, id, idLast, memberFxn

ここで、斜体のパラメーターに置き換えられます:

wNotifyCode

通知メッセージ、 LVN_KEYDOWNなどを処理するコード。

id

連続する範囲の識別子の最初の識別子。

idLast

連続する範囲の識別子の最後の識別子。

memberFxn

この通知が送信されるときに呼び出されるメンバー関数。

メンバー関数は、次のプロトタイプを宣言する必要があります。:

afx_msgvoidmemberFxn(UINT id、NMHDRpNotifyStruct,LRESULT結果);

斜体のパラメーターが:

id

通知を送信したコントロールの子の識別子。

pNotifyStruct

上記のとおり、通知の構造体へのポインター。

結果

結果コードへのポインターを返す前に設定します。

ON_NOTIFY_EX、ON_NOTIFY_EX_RANGE

1 つ以上のオブジェクトの通知メッセージを処理するためにルーティングする場合は、 ON_NOTIFY (またはON_NOTIFY_RANGE) ではなくON_NOTIFY_EX (またはON_NOTIFY_EX_RANGE) を使用できます。EX版と通常版の唯一の違いは、 EXバージョンに対して呼び出されるメンバー関数はメッセージ処理を続行する必要があるかどうかを示すブール値を返すことです。この関数からFALSEを返す 1 つ以上のオブジェクトで同じメッセージを処理することができます。

ClassWizard では、 ON_NOTIFY_EXまたはON_NOTIFY_EX_RANGEは処理されません。それらのいずれかを使用する場合は、自分のメッセージ マップを編集する必要があります。

メッセージ マップのエントリと関数のプロトタイプON_NOTIFY_EXON_NOTIFY_EX_RANGEを次のとおりです。パラメーターの意味は、以外のと同じです-EXバージョン。

ON_NOTIFY_EX ( nCode, id, memberFxn

ON_NOTIFY_EX_RANGE ( wNotifyCode, id, idLast,memberFxn

上記の両方のためのプロトタイプは同じです。:

afx_msgBOOLmemberFxn(UINT id、NMHDRpNotifyStruct,LRESULT結果);

両方のケースでは、 id通知を送信するコントロールの子の識別子を保持します。

関数TRUE場合は、通知メッセージを完全に処理されているまたは他のオブジェクトのコマンド ルーティングの場合はFALSEメッセージを処理する機会があります。 返す必要があります。

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

Index