このコマンドのルーティングとディスパッチのアーキテクチャとして一般的なウィンドウ メッセージ ルーティングで高度なトピックについて説明します。
Visual の C++ プログラマのガイドをここで説明したアーキテクチャの詳細は Windows メッセージ、コントロール通知、およびコマンドの区別特にください。このマニュアルで説明されている問題に非常に精通しているし、は非常に高度なトピックのアドレスと見なされます。
コマンド ルーティングとディスパッチに関する MFC 1.0 Mfc に 2.0 のアーキテクチャ
Windows メニュー コマンド、アクセラレータキー、ダイアログ コントロール通知の通知を提供するオーバー ロードは、 WM_COMMANDメッセージをが。
MFC 1.0 で少しはCWndのコマンド ハンドラー (たとえば、「OnFileNew」) を許可することにより構築に応答して特定のWM_COMMANDと呼ばれる取得するクラスを派生します。これは、メッセージ マップと呼ばれるデータ構造と接着しているし、非常にスペース効率の良いコマンド機構の結果。
MFC 1.0 は、コントロール通知コマンド メッセージから分離するための追加機能も提供。コマンドは、コマンド ID として知られて、16 ビット ID によって表されるコマンドが正常に起動はCFrameWndから (例えば: メニュー選択またはアクセラレータ キー) とさまざまな他のウィンドウに送られます。
MFC 1.0、狭い意味での複数ドキュメント インターフェイス (MDI) の実装でのコマンドのルーティングを使用します。(MDI フレーム ウィンドウ、アクティブな MDI 子ウィンドウにコマンドを委任します。)
この機能の一般化されておりオブジェクト (ウィンドウ オブジェクトだけではなく) の広い範囲で処理するコマンドを許可するには、MFC 2.0 で拡張します。それより正式な提供し、ルーティングのための拡張可能なアーキテクチャ メッセージ、コマンド ターゲットはコマンドの処理だけでなくユーザー インターフェイス オブジェクト (メニュー項目やツール バー ボタン) のコマンドの現在の可用性を反映するように更新ルーティング再利用。
コマンド Id
Visual の C++ プログラマのガイドでは、ルーティングとバインディングは、コマンドの説明を参照してください。テクニカル ノート 20 にはID の名前付けに関する情報が含まれています。
我々 は汎用のプリフィックス「id _」のコマンド Id を使用します。コマンド Id は gt; 0x8000 =。メッセージ行やステータス バーとコマンド ID と同じ Id を持つ STRINGTABLE リソースがあるかどうかは、コマンドを説明する文字列が表示されます。(&G)。
アプリケーションのリソースでは、いくつかの場所でのコマンド ID が表示されます。:
アプリケーションのソース コードでは、いくつかの場所でのコマンド ID の表示します。:
現在、唯一の実装のコマンド Id を必要とする MFC が gt; = 0x8000 です GOSUB ダイアログ ・ コマンドの実装(&G)。
GOSUB コマンド、ダイアログ ボックスでコマンド アーキテクチャを使用して
ルーティングのコマンドを有効にするコマンド アーキテクチャは、フレーム ウィンドウ、メニュー項目、ツールバー ボタン、ダイアログ バー ボタンのコントロール バー、需要とルート コマンドを更新するコントロールの Id をメイン コマンド ターゲット (通常、メイン フレーム ウィンドウ) に設計された他のユーザー インターフェイス要素にも動作します。メイン コマンド ターゲット コマンドまたはコントロール通知その他コマンド ターゲット オブジェクトを適切にルーティング可能性があります。
適切なコマンド ID ダイアログ コントロールのコントロール ID を割り当てる場合にダイアログ ボックス (モーダルまたはモードレス) コマンド アーキテクチャの機能のいくつかから恩恵を受けることができます。いくつか追加のコードを記述する必要がありますようにダイアログ ボックスのサポートは自動ではないです。
正常に動作するこれらの機能をあなたのコマンド Id gt ことが必要です、0x8000 =。多くのダイアログを同じフレームにルーティングを得ることができるので、共有コマンドをする必要があります > = 0x8000、非共有 IDC の特定のダイアログ ボックスでする必要があります < 0x7FFF を =。
モーダル ダイアログで、適切なコマンド ID の設定、ボタンの IDC では、通常のボタンを置くことができます。ユーザーがボタンを選択すると、他のコマンドと同じようにコマンド (通常は、メイン フレーム ウィンドウ) ダイアログ ボックスの所有者を取得します。通常、別 (最初のダイアログ ボックスの GOSUB) ダイアログを使用するためこの GOSUB コマンドと呼ばれます。
また、ダイアログ ボックスで、関数CWnd::UpdateDialogControlsを呼び出すことができ、メイン フレーム ウィンドウのアドレスを渡します。この機能が有効または無効にするかどうか、コマンド ハンドラーがフレーム中にあるダイアログ コントロールをベースしました。この自動的にあなたのアプリケーションのアイドル ループ、コントロール バーに対して呼び出されますが、この機能を持ちたい通常ダイアログを直接呼び出す必要があります。
ON_UPDATE_COMMAND_UI が呼び出されたとき
有効にチェック状態をプログラムのすべてのメニュー項目のすべての時間を維持する、負荷の問題をすることができます。一般的な技法を有効にする/メニュー項目だけが、ポップアップを選択するとチェックすることです。MFC 2.0 のCFrameWnd WM_INITMENUPOPUPメッセージの処理し、コマンド ルーティング アーキテクチャを使用して、メニューをON_UPDATE_COMMAND_UIハンドラーの状態を確認するには。
CFrameWndもステータス バー (メッセージ行とも呼ばれます) で選択した項目を現在のメニューを記述するために、 WM_ENTERIDLEメッセージを処理します。
Visual C で編集、アプリケーションのメニュー構造、 WM_INITMENUPOPUP時に使用できる潜在的なコマンドを表すために使用します。ON_UPDATE_COMMAND_UIハンドラーの状態や、メニューのテキストを変更したり、メニューが描画される前に高度な用途 (のようなファイル MRU リストまたは OLE 動詞のポップアップ メニュー) 実際にメニュー構造を変更します。
ON_UPDATE_COMMAND_UI処理のツールバーだ (およびその他のコントロール バー) は、アプリケーションがアイドル ループに入る。クラス ライブラリ リファレンステクニカル ノート 31コントロール バーの詳細について参照してください。
入れ子になったポップアップ メニュー
ネストされたメニュー構造を使用している場合は、2 つの異なる場合、最初のメニュー項目、ポップアップのON_UPDATE_COMMAND_UIハンドラーが呼び出されることがわかります。
まず、ポップアップのと呼ばれます。これは、ポップアップ メニューの Id がないと、ポップアップの最初のメニュー項目の ID を使用して、全体のポップアップを参照してくださいするために必要です。この場合、 CCmdUIオブジェクトのm_pSubMenuメンバー変数は非 NULL になります、ポップアップ メニューをポイントします。
第二にだけ、メニュー項目、ポップアップで描画する前に呼び出されます。この場合は、最初のメニュー項目には、ID を参照し、 CCmdUIオブジェクトのm_pSubMenuメンバー変数は NULL になります。
これは、メニュー項目から、個別のポップアップを有効にすることができますが、メニューを認識してコードを記述することが必要です。たとえば、入れ子になったメニューに次の構造:
Filegt;新しい >シート (ID_NEW_SHEET)グラフ (ID_NEW_CHART)
ID_NEW_SHEET と ID_NEW_CHART コマンドは、個別に有効または無効にすることができます。2 つのいずれかが有効な場合、「新規」ポップアップ メニュー有効にしてください。
ID_NEW_SHEET (ポップアップの最初のコマンド) のコマンド ハンドラーのようになります:
void CMyApp::OnUpdateNewSheet (CCmdUI ※ pCmdUI){特価;場合 (pCmdUI - > m_pSubMenu! = NULL){・ ・「New」のシート、グラフ全体ポップアップ有効にするBOOL bEnable m_bCanCreateSheet = | |m_bCanCreateChart;・ CCmdUI::Enable は no-op この場合は、これは//は何をするいるとする必要があります。pCmdUI - > m_pMenu - > EnableMenuItem (pCmdUI - > m_nIndex、MF_BYPOSITION |(bEnable ですか?MF_ENABLED: (項目 |MF_GRAYED)));戻る;}//それ以外の場合は、新しいシート コマンドpCmdUI - > Enable(m_bCanCreateSheet);}
ID_NEW_CHART のコマンド ハンドラーは次のよう、通常の更新コマンド ハンドラーだろう:
void CMyApp::OnUpdateNewChart (CCmdUI ※ pCmdUI){特価;pCmdUI - > Enable(m_bCanCreateChart);}
ON_COMMAND と ON_BN_CLICKED
メッセージ マップ マクロのON_COMMANDとON_BN_CLICKEDは同じです。MFC のコマンドとコントロール通知ルーティング機構は、のみにコマンド ID を使用して、ルーティングを決定します。コントロール通知コードとコントロール通知ゼロ (BN_CLICKED) のコマンドとして解釈されます。
高度なメモ: 実際には、すべてのコントロール通知メッセージ、コマンド ハンドラー チェインを通じて移動します。したがって、ドキュメント クラスで言うEN_CHANGEコントロール通知ハンドラーを記述する技術的に可能です。これ以来、この機能の実用的なアプリケーションのいくつかは、ClassWizard では、機能がサポートされていません、機能を使用するコードが脆弱になります通常勧められない。
ボタン コントロールの自動無効化無効化
ダイアログ バー、またはダイアログ ボックスはCWnd::UpdateDialogControlsに独自呼んでいるを使用するボタン コントロールを配置する場合、 ON_COMMANDまたはON_UPDATE_COMMAND_UIハンドラーを持たないボタン自動的にあなたのために、フレームワークによってできなくなることがわかります。いくつかのケースでは、ハンドラーが必要はありませんが、ボタンを有効にしておくことを勧めします。これを実現する最も簡単な方法 (ClassWizard を行うには簡単な) ダミー コマンド ハンドラーを追加するには、何それ。
ウィンドウのメッセージ ルーティング
MFC クラスと Windows メッセージのルーティングとその他のトピックを影響する方法でのいくつかのより高度なトピックを以下に示します。ここでの情報のみ簡単に説明します。パブリック Api についての詳細をクラス ライブラリのリファレンスを参照してください。MFC ライブラリのソース コードの実装の詳細についてを参照してください。
テクニカル ノート 17ウィンドウのクリーンアップの詳細について、非常に重要なトピックをすべてCWndをください-派生クラス。
CWnd の問題
実装メンバー関数CWnd::OnChildNotifyフックまたはそれ以外の場合のメッセージ、コマンド、およびその親 (または「所有者」) に移動するコントロール通知の通知子ウィンドウ (コントロールとも呼ばれます) を、強力かつ拡張可能なアーキテクチャを提供します。場合は、子ウィンドウ (/) は、C++ のCWndオブジェクト自体は、 OnChildNotifyは最初パラメーターで、元のメッセージから (つまり、 MSG構造体)、仮想関数です。子ウィンドウことができますだけで、メッセージを残す、食べるか、または、メッセージ (まれに) の親の変更。
CWndの既定の実装、次のメッセージを処理し、 OnChildNotifyフックを使用して、子ウィンドウ (コントロール) を取得する最初のメッセージで亀裂を許可するには:
自己描画メッセージにオーナー描画メッセージを変更するため、 OnChildNotifyフックが使用されることがわかります。
OnChildNotifyフックに加え、スクロール メッセージはさらにルーティング動作があります。下のスクロール バーとソースWM_HSCROLLおよびWM_VSCROLLメッセージの詳細をご覧ください。
CFrameWnd の問題
CFrameWndクラスほとんど、コマンド ルーティングとユーザー インターフェイスの提供の実装を更新します。これは、アプリケーション (CWinApp::m_pMainWnd) のメイン フレーム ウィンドウを主に使用されます。 が、すべてのフレーム ウィンドウに適用されます。
メイン フレーム ウィンドウ、ウィンドウ、メニュー バーとステータス バーの親またはメッセージ行。コマンド ルーティングに上記の議論を参照してください、 WM_INITMENUPOPUP 。
CFrameWndクラス管理、アクティブなビューを提供します。次のメッセージ、アクティブなビューを通じてルーティングされます。:
CMDIFrameWnd/CMDIChildWnd 問題
両方 MDI フレーム ウィンドウ クラスはCFrameWndから派生し、したがって両方同じ一種のコマンド ルーティングと、 CFrameWndで提供されるユーザー インターフェイスの更新を有効にします。典型的な MDI アプリケーションでは、メイン フレーム ウィンドウ (つまりCMDIFrameWndオブジェクト) のみメニュー バーとステータス バーを保持し、したがって、コマンド ルーティングの実装の主なソースです。
一般的なルーティング スキームは、at コマンドの最初の亀裂をアクティブな MDI 子ウィンドウに取得されます。両方の MDI 子ウィンドウのアクセラレータ テーブル (最初) 既定PreTranslateMessage関数を処理し、MDI フレーム (2 番目) 通常TranslateMDISysAccelで (最後) の処理、標準の MDI システム コマンド アクセラレータとしてだけでなく、。
スクロール バーの問題
スクロール メッセージを処理するとき (WM_HSCROLL/OnHScrollおよびWM_VSCROLL/OnVScroll ) は、スクロール バー メッセージから来たは依存しないので、ハンドラー コードを記述しようとする必要があります。スクロール メッセージがスクロール バー コントロールからまたはWS_HSCROLLから来ることができるのでこれはのみ一般的な Windows の問題ではない/がWS_VSCROLLスクロール バーしないスクロール バー コントロール。
MFC はスクロール バー コントロールの子または兄弟 (実際には、スクロール バーとスクロールされるウィンドウの親と子の関係が何かをすることができます) がスクロールされるウィンドウのいずれかを許可するように拡張します。これは、共有スクロール バー分割ウィンドウでは特に重要です。テクニカル ノート 29共有スクロール バーに関する詳細を含むCSplitterWndの実装の詳細を参照してください。
側メモで、時間の場所で指定されたスクロール バーのスタイルを作成する、派生クラスのトラップされ、Windows に渡されない 2 CWndです。作成ルーチンに渡されるときに、 WS_HSCROLLとWS_VSCROLL独立して設定できるが後に作成を変更することができます。もちろん、直接テストまたは、ws _ を設定する必要がありますか?作成ウィンドウのスタイル ビットをスクロールします。
CMDIFrameWndを作成またはLoadFrameを渡す、スクロール バーのスタイルは、MDICLIENT を作成に使用されます。設定するのには、必ず、スクロール可能な MDICLIENT 領域 (のような Windows プログラム マネージャー) を持ちたい場合両方バーのスタイルをスクロール (WS_HSCROLL |WS_VSCROLL)CMDIFrameWndを作成に使用するスタイル。
CSplitterWndはスプリッターの特別な共有スクロール バー、スクロール バーのスタイルを適用します。静的分割ウィンドウでは、どちらのスクロール バーのスタイルを設定します通常ないです。動的分割ウィンドウでは、通常、スクロール バーのスタイル セットに分割され、方向列を分割することができる場合、 WS_VSCROLLの行を分割することができる場合は、この方針の必要があります。
番号順テクニカル ノート|nbsp;カテゴリ別テクニカル ノート(&N)