次の方法で共有


TN028: Context-Sensitive ヘルプ サポート

このメモでは、MFC でヘルプ コンテキスト ID やその他のヘルプの問題を割り当てる規則について説明します。 状況依存ヘルプのサポートには、Visual C++ で使用できるヘルプ コンパイラが必要です。

MFC では、WinHelp を使用した状況依存ヘルプの実装に加えて、HTML ヘルプの使用もサポートされています。 このサポートと HTML ヘルプを使用したプログラミングの詳細については、「 HTML ヘルプ: プログラムのヘルプを Context-Sensitive する」を参照してください。

サポートされるヘルプの種類

Windows アプリケーションには、2 種類の状況依存ヘルプが実装されています。 1 つ目は "F1 ヘルプ" と呼ばれ、現在アクティブなオブジェクトに基づいて適切なコンテキストで WinHelp を起動します。 2 つ目は "Shift + F1" モードです。 このモードでは、マウス カーソルがヘルプ カーソルに変わり、ユーザーはオブジェクトをクリックします。 その時点で、ユーザーがクリックしたオブジェクトのヘルプを表示するために WinHelp が起動します。

Microsoft Foundation Classes では、これらの両方の形式のヘルプが実装されています。 さらに、このフレームワークでは、ヘルプ インデックスとヘルプの使用という 2 つの簡単なヘルプ コマンドがサポートされています。

ヘルプ ファイル

Microsoft Foundation クラスは、1 つのヘルプ ファイルを想定しています。 そのヘルプ ファイルの名前とパスは、アプリケーションと同じである必要があります。 たとえば、実行可能ファイルが C:\MyApplication\MyHelp.exe されている場合、ヘルプ ファイルは C:\MyApplication\MyHelp.hlp である必要があります。 CWinApp クラスm_pszHelpFilePath メンバー変数を使用してパスを設定します。

ヘルプ コンテキスト範囲

MFC の既定の実装では、ヘルプ コンテキスト ID の割り当てに関するいくつかの規則に従うプログラムが必要です。 これらの規則は、特定のコントロールに割り当てられた ID の範囲です。 ヘルプ関連のさまざまなメンバー関数のさまざまな実装を提供することで、これらの規則をオーバーライドできます。

0x00000000 - 0x0000FFFF : user defined
0x00010000 - 0x0001FFFF : commands (menus/command buttons)
0x00010000 + ID_
(note: 0x18000-> 0x1FFFF is the practical range since command IDs are>=0x8000)
0x00020000 - 0x0002FFFF : windows and dialogs
0x00020000 + IDR_
(note: 0x20000-> 0x27FFF is the practical range since IDRs are <= 0x7FFF)
0x00030000 - 0x0003FFFF : error messages (based on error string ID)
0x00030000 + IDP_
0x00040000 - 0x0004FFFF : special purpose (non-client areas)
0x00040000 + HitTest area
0x00050000 - 0x0005FFFF : controls (those that are not commands)
0x00040000 + IDW_

単純な "ヘルプ" コマンド

Microsoft Foundation クラスによって実装される 2 つの簡単なヘルプ コマンドがあります。

最初のコマンドは、アプリケーションのヘルプ インデックスを示しています。 2 つ目は、WinHelp プログラムの使用に関するユーザーのヘルプを示しています。

Context-Sensitive ヘルプ (F1 ヘルプ)

F1 キーは、通常、メイン ウィンドウのアクセラレータ テーブルに配置されたアクセラレータによってID_HELPの ID を持つコマンドに変換されます。 ID_HELP コマンドは、メイン ウィンドウまたはダイアログ ボックスにID_HELPの ID を持つボタンによって生成される場合もあります。

ID_HELP コマンドの生成方法に関係なく、コマンド ハンドラーに到達するまで、通常のコマンドとしてルーティングされます。 MFC コマンド ルーティング アーキテクチャの詳細については、 テクニカル ノート 21 を参照してください。 アプリケーションでヘルプが有効になっている場合、ID_HELP コマンドは CWinApp::OnHelp によって処理されます。 アプリケーション オブジェクトはヘルプ メッセージを受け取り、コマンドを適切にルーティングします。 これは、既定のコマンド ルーティングが最も具体的なコンテキストを決定するのに適していないために必要です。

CWinApp::OnHelp は、次の順序で WinHelp を起動しようとします。

  1. ヘルプ ID を使用してアクティブな AfxMessageBox 呼び出しを確認します。 メッセージ ボックスが現在アクティブな場合は、そのメッセージ ボックスに適したコンテキストで WinHelp が起動されます。

  2. WM_COMMANDHELP メッセージをアクティブ ウィンドウに送信します。 そのウィンドウが WinHelp を起動しても応答しない場合、メッセージが処理されるか、現在のウィンドウが最上位ウィンドウになるまで、同じメッセージがそのウィンドウの先祖に送信されます。

  3. ID_DEFAULT_HELP コマンドをメイン ウィンドウに送信します。 これにより、既定のヘルプが呼び出されます。 このコマンドは通常、 CWinApp::OnHelpIndexにマップされます。

既定の ID 基本値 (コマンドの0x10000やダイアログなどのリソースの0x20000など) をグローバルにオーバーライドするには、アプリケーションで CWinApp::WinHelp をオーバーライドする必要があります。

この機能とヘルプ コンテキストの決定方法をオーバーライドするには、WM_COMMANDHELP メッセージを処理する必要があります。 フレームワークが提供するよりも具体的なヘルプ ルーティングを提供することもできます。これは、現在の MDI 子ウィンドウと同じ深さだけであるためです。 また、特定のウィンドウまたはダイアログについて、そのオブジェクトの現在の内部状態またはダイアログ内のアクティブなコントロールに基づいて、より具体的なヘルプを提供することもできます。

WM_COMMANDHELP

afx_msg LRESULT CWnd::OnCommandHelp(WPARAM wParam, LPARAM lParam)

WM_COMMANDHELPは、ヘルプが要求されたときにアクティブ ウィンドウによって受信されるプライベート Windows MFC メッセージです。 ウィンドウがこのメッセージを受信すると、ウィンドウの内部状態に一致するコンテキストで CWinApp::WinHelp を呼び出す場合があります。

lParam
現在使用可能なヘルプ コンテキストが含まれています。 ヘルプ コンテキストが決定されていない場合、lParam は 0 です。 OnCommandHelpの実装では、lParam のコンテキスト ID を使用して別のコンテキストを判断したり、CWinApp::WinHelpに渡すことができます。

wParam する
使用されず、0 になります。

OnCommandHelp関数がCWinApp::WinHelpを呼び出す場合は、TRUE を返す必要があります。 TRUE を返す他のクラスと他のウィンドウにこのコマンドのルーティングを停止します。

ヘルプ モード (Shift + F1 ヘルプ)

これは、状況依存のヘルプの 2 番目の形式です。 通常、このモードは Shift キーを押しながら F1 キーを押すか、メニュー/ツール バーを使用して入力します。 これはコマンド (ID_CONTEXT_HELP) として実装されます。 メッセージ フィルター フックは、モーダル ダイアログ ボックスまたはメニューがアクティブな間にこのコマンドを変換するために使用されないため、このコマンドは、アプリケーションがメイン メッセージ ポンプ (CWinApp::Run) を実行している場合にのみユーザーが使用できます。

このモードに入ると、アプリケーションが通常その領域に対して独自のカーソル (ウィンドウの周囲のサイズ変更罫線など) を表示する場合でも、アプリケーションのすべての領域にヘルプ マウス カーソルが表示されます。 ユーザーは、マウスまたはキーボードを使用してコマンドを選択できます。 コマンドを実行する代わりに、そのコマンドのヘルプが表示されます。 また、ツール バーのボタンなど、画面上に表示されているオブジェクトをクリックすると、そのオブジェクトのヘルプが表示されます。 このヘルプ モードは、 CWinApp::OnContextHelpによって提供されます。

このループの実行中、メニューにアクセスするキーを除き、すべてのキーボード入力が非アクティブになります。 また、コマンド変換は、ユーザーがアクセラレータ キーを押してそのコマンドのヘルプを受け取ることができるように、 PreTranslateMessage を介して実行されます。

shift キーを押しながら F1 ヘルプ モードで実行してはならない特定の翻訳やアクションが PreTranslateMessage 関数で実行されている場合は、それらの操作を実行する前に、CWinAppm_bHelpMode メンバーを確認する必要があります。 たとえば、PreTranslateMessageCDialog実装では、IsDialogMessageを呼び出す前にこれをチェックします。 これにより、Shift + F1 モード時のモードレス ダイアログの "ダイアログ ナビゲーション" キーが無効になります。 さらに、このループ中も CWinApp::OnIdle が呼び出されます。

ユーザーがメニューからコマンドを選択すると、そのコマンドのヘルプとして処理されます (WM_COMMANDHELP、以下を参照)。 ユーザーがアプリケーション ウィンドウの表示領域をクリックすると、非クライアント クリックかクライアント クリックかを判断します。 OnContextHelp は、クライアント以外のクリックからクライアントクリックへのマッピングを自動的に処理します。 クライアントクリックの場合は、クリックされたウィンドウにWM_HELPHITTESTを送信します。 そのウィンドウが 0 以外の値を返す場合、その値はヘルプのコンテキストとして使用されます。 0 を返した場合、 OnContextHelp は親ウィンドウを試行します (失敗した場合、その親ウィンドウなど)。 ヘルプ コンテキストを特定できない場合、既定では、メイン ウィンドウにID_DEFAULT_HELP コマンドが送信され、その後 (通常は) CWinApp::OnHelpIndexにマップされます。

WM_HELPHITTEST

afx_msg LRESULT CWnd::OnHelpHitTest(
WPARAM, LPARAM lParam)

WM_HELPHITTESTは、SHIFT + F1 ヘルプ モード中にクリックされたアクティブ ウィンドウによって受信される MFC プライベート ウィンドウ メッセージです。 ウィンドウは、このメッセージを受信すると、WinHelp で使用する DWORD ヘルプ ID を返します。

LOWORD(lParam) には、ウィンドウのクライアント領域を基準にマウスがクリックされた X 軸デバイス座標が含まれています。

HIWORD(lParam) には、Y 軸の座標が含まれています。

wParam する
は使用されず、0 になります。 戻り値が 0 以外の場合は、そのコンテキストで WinHelp が呼び出されます。 戻り値が 0 の場合、親ウィンドウにヘルプが照会されます。

多くの場合、既にある可能性があるヒット テスト コードを利用できます。 WM_HELPHITTEST メッセージを処理する例については、 CToolBar::OnHelpHitTest の実装を参照してください (コードでは、 CControlBarのボタンとヒントで使用されるヒット テスト コードを利用します)。

MFC アプリケーション ウィザードのサポートと MAKEHM

MFC アプリケーション ウィザードでは、ヘルプ ファイル (.cnt ファイルと .hpj ファイル) をビルドするために必要なファイルが作成されます。 また、Microsoft ヘルプ コンパイラが受け入れる事前構築済みの.rtf ファイルも多数含まれています。 トピックの多くは完全ですが、特定のアプリケーションに対して変更が必要な場合があります。

"ヘルプ マッピング" ファイルの自動作成は、MAKEHM というユーティリティによってサポートされます。 MAKEHM ユーティリティは、アプリケーションの RESOURCE を変換できます。H ファイルをヘルプ マッピング ファイルに追加します。 例えば次が挙げられます。

#define IDD_MY_DIALOG   2000
#define ID_MY_COMMAND   150

は次のように変換されます。

HIDD_MY_DIALOG    0x207d0
HID_MY_COMMAND    0x10096

この形式はヘルプ コンパイラの機能と互換性があり、コンテキスト ID (右側の数字) をトピック名 (左側の記号) にマップします。

MAKEHM のソース コードは、MFC プログラミング ユーティリティのサンプル MAKEHM で入手できます。

MFC アプリケーション ウィザードの実行後のヘルプ サポートの追加

アプリケーションにヘルプを追加する最善の方法は、アプリケーションを作成する前に、MFC アプリケーション ウィザードの [高度な機能] ページで [状況依存のヘルプ] オプションをオンにすることです。 そうすることで、MFC アプリケーション ウィザードは、ヘルプをサポートするために必要なメッセージ マップ エントリを CWinApp派生クラスに自動的に追加します。

メッセージ ボックスのヘルプ

メッセージ ボックス (アラートとも呼ばれます) のヘルプは、MessageBox Windows API のラッパーである AfxMessageBox 関数を通じてサポートされます。

AfxMessageBoxには 2 つのバージョンがあります。1 つは文字列 ID で使用し、もう 1 つは文字列へのポインター (LPCSTR) で使用します。

int AFXAPI AfxMessageBox(LPCSTR lpszText,
    UINT nType,
    UINT nIDHelp);

int AFXAPI AfxMessageBox(UINT nIDPrompt,
    UINT nType,
    UINT nIDHelp);

どちらの場合も、オプションのヘルプ ID があります。

最初のケースでは、nIDHelp の既定値は 0 で、このメッセージ ボックスのヘルプがないことを示します。 メッセージ ボックスがアクティブな状態でユーザーが F1 キーを押した場合、ユーザーはヘルプを受け取りません (アプリケーションがヘルプをサポートしている場合でも)。 これが望ましくない場合は、nIDHelp にヘルプ ID を指定する必要があります。

2 番目のケースでは、nIDHelp の既定値は -1 で、ヘルプ ID が nIDPrompt と同じであることを示します。 ヘルプは、アプリケーションがヘルプ対応の場合にのみ機能します)。 メッセージ ボックスにヘルプのサポートがない場合は、nIDHelp に 0 を指定する必要があります。 メッセージをヘルプとして有効にしたいが、nIDPrompt とは異なるヘルプ ID が必要な場合は、nIDPrompt とは異なる nIDHelp に正の値を指定するだけです。

こちらも参照ください

番号別テクニカル ノート
カテゴリ別テクニカル ノート