.NET TIPS

任意の位置にポップアップ・ヘルプを表示するには?

デジタルアドバンテージ 一色 政彦
2005/12/02

 「TIPS:Windowsフォームでポップアップ・ヘルプを表示するには?」では、Windowsアプリケーションのダイアログで「ポップアップ・ヘルプ」(「バルーン・ヘルプ」とも呼ばれる)を表示する方法を紹介した。

 しかしこのTIPSの方法でポップアップ・ヘルプの表示を実装した場合、常にマウス・カーソルの近くにポップアップ・ヘルプが表示される仕様になる。このため、確かにタイトルバーの[?]ボタンをマウスでクリックしてからポップアップ・ヘルプを表示した場合には(以降、[?]クリック)適切な位置になるが、[F1]キーでポップアップ・ヘルプを表示した場合は(以降、[F1]キー押下)、マウス・カーソルの位置が離れていればそのカーソル付近にヘルプが表示されてしまうため、非常に見にくい。例えば次の画面のようになってしまう。

[F1]キーによりポップアップ・ヘルプが思いもよらぬ場所に表示された例
[F1]キーを押してポップアップ・ヘルプを表示した場合、常にマウス・カーソルの位置に表示する仕様のため、コントロールからかけ離れた場所に表示されることがある。

 本稿ではこの問題を回避してポップアップ・ヘルプを適切な位置に表示する方法を紹介する。

 なお途中(タイトルバーへの[?]ボタンの追加)までの実装手順は前掲のTIPSと同じである。前掲のTIPSでは、HelpProviderオブジェクト(System.Windows.Forms名前空間)をインスタンス化してポップアップ・ヘルプの表示設定(具体的には、ShowHelpプロパティやSetHelpStringメソッドの呼び出し)を行った。これにより、[?]クリックと[F1]キー押下で自動的にポップアップ・ヘルプが表示されるようになったが、本稿ではこの機能を利用せずに完全に自前でポップアップ・ヘルプの表示を実装する。

ポップアップ・ヘルプの表示機能

 ここでは、ポップアップ・ヘルプを表示するためのShowPopupHelpメソッドを作成する。

 このメソッドの内部では、[?]クリックなのか、[F1]キー押下なのかを判定するための簡略的なロジックとして、マウス・カーソルがコントロールの内部にあるのか([?]クリック)、それとも外部にあるのか([F1]キー押下)を確認するコードを実装する(この方法は厳密な意味では正しくないが、本稿ではコードを短く簡略化するためこのようにしている)。コントロールの内部か外部かを判定する方法は、「TIPS:ある座標や領域がコントロールの領域内に含まれているかを確認するには?」を参照してほしい。

 マウス・カーソルの座標がコントロールの内部にあればマウス・カーソルの位置にポップアップ・ヘルプを表示し、外部にあればコントロールの下辺中央の位置にポップアップ・ヘルプを表示する。

 任意の位置にポップアップ・ヘルプを表示するには、Helpクラス(System.Windows.Forms名前空間)の静的メソッドShowPopupを使えばよい。ShowPopupメソッドは、第1パラメータに親コントロールを、第2パラメータにヘルプ文字列を、第3パラメータに表示する位置のスクリーン座標を指定する。戻り値はない。

 以上の内容を、ShowPopupHelpメソッドの内部に実装したのが、次のコードだ。なおShowPopupHelpメソッドのパラメータには、内部で必要となる親コントロールを指定する。

private void ShowPopupHelp(Control ctrl)
{
  // マウス座標(スクリーン座標系)の取得
  Point mouseScreenPos = Control.MousePosition;
  // マウス座標をクライアント座標系へ変換
  Point mouseClientPos = ctrl.PointToClient(mouseScreenPos);
  // コントロールのクライアント領域を取得
  Rectangle rect = ctrl.ClientRectangle;
  // マウス座標(クライアント座標系)が領域内かどうか
  bool inside = rect.Contains(mouseClientPos);
  if (inside)
  {  // 内部

    // ポップアップ・ヘルプを表示する
    Help.ShowPopup(ctrl,
      "ポップアップ・ヘルプです。\n(コントロール内部)",
      mouseScreenPos);
  }
  else
  {  // 外部

    // コントロールの下辺中央の位置を取得する
    Point ctrlClietnPos = new Point(ctrl.Size.Width / 2, ctrl.Size.Height);
    // 取得した位置をスクリーン座標系に変換する
    Point ctrlScreenPos = ctrl.PointToScreen(ctrlClietnPos);
    // ポップアップ・ヘルプを表示する
    Help.ShowPopup(ctrl,
      "ポップアップ・ヘルプです。\n(コントロール外部)",
      ctrlScreenPos);
  }
}
Private Sub ShowPopupHelp(ByVal ctrl As Control)
  ' マウス座標(スクリーン座標系)の取得
  Dim mouseScreenPos As Point = Control.MousePosition
  ' マウス座標をクライアント座標系へ変換
  Dim mouseClientPos As Point =  ctrl.PointToClient(mouseScreenPos)
  ' コントロールのクライアント領域を取得
  Dim rect As Rectangle =  ctrl.ClientRectangle
  ' マウス座標(クライアント座標系)が領域内かどうか
  Dim inside As Boolean =  rect.Contains(mouseClientPos)

  If inside Then
    ' 内部

    ' ポップアップ・ヘルプを表示する
    Help.ShowPopup(ctrl, _
      "ポップアップ・ヘルプです。" & vbLf & "(コントロール内部)", _
      mouseScreenPos)

  Else
    ' 外部

    ' コントロールの下辺中央の位置を取得する
    Dim ctrlClietnPos As Point =  New Point(ctrl.Size.Width / 2,ctrl.Size.Height)
    ' 取得した位置をスクリーン座標系に変換する
    Dim ctrlScreenPos As Point =  ctrl.PointToScreen(ctrlClietnPos)
    ' ポップアップ・ヘルプを表示する
    Help.ShowPopup(ctrl, _
      "ポップアップ・ヘルプです。" & vbLf & "(コントロール外部)", _
      ctrlScreenPos)
  End If

End Sub
ポップアップ・ヘルプを表示するShowPopupHelpメソッド(上:C#、下:VB.NET)

 後はこのShowPopupHelpメソッドを[?]クリックと[F1]キー押下があったときに呼び出すようにすれば完成だ。

HelpRequestedイベント・ハンドラの実装

 [?]クリックと[F1]キー押下のタイミングは、.NET Frameworkでは、HelpRequestedイベント(=ユーザーがコントロールのヘルプを表示するときに発生するイベント)として定義されている。従って、ポップアップ・ヘルプを表示したいコントロールに対して、HelpRequestedイベント・ハンドラを追加すればよいわけだ。なおこのイベント・ハンドラは、ポップアップ・ヘルプを表示したいすべてのコントロールに対して追加する必要がある。

 HelpRequestedイベント・ハンドラの内部では、先ほど作成したShowPopupHelpメソッドの呼び出しを記述する。具体的には次のようなコードになる。

private void button1_HelpRequested(object sender, System.Windows.Forms.HelpEventArgs hlpevent)
{
  // ポップアップ・ヘルプを表示する
  ShowPopupHelp(button1);
  // HelpRequestedイベントを処理済みに設定する
  hlpevent.Handled = true;
}
Private Sub button1_HelpRequested(ByVal sender As Object, ByVal hlpevent As System.Windows.Forms.HelpEventArgs) Handles button1.HelpRequested
  ' ポップアップ・ヘルプを表示する
  ShowPopupHelp(button1)
  ' HelpRequestedイベントを処理済みに設定する
  hlpevent.Handled = True
End Sub
[?]クリックと[F1]キー押下でポップアップを表示するHelpRequestedイベント・ハンドラ(上:C#、下:VB.NET)
Visual Studioを使っている場合ならば、イベント・ハンドラの追加は、C#はWindowsデザイナでフォームのデザインを表示している状態で[プロパティ]ウィンドウから追加できる。Visual Basicはコード・エディタでフォームのコードを表示している状態でエディタ上部のナビゲーション・バーから追加できる。

 HelpRequestedイベント・ハンドラは、第2パラメータにHelpEventArgクラス(System.Windows.Forms名前空間)のオブジェクトを受け取る。HelpEventArgオブジェクト(上記コードでは「hlpevent」という変数)はヘルプ・イベント関連の情報を通知するためのもので、具体的にはそのHandledプロパティでHelpRequestedヘルプ・イベントが処理済みかどうかを取得・設定でき、MousePosプロパティでマウス・カーソルのスクリーン座標での位置を取得できる。本稿ではマウス・カーソルのスクリーン座標は、(ShowPopupHelpメソッド内部で)「Control.MousePositionプロパティ」を使って取得しているが、このMousePosプロパティを使うこともできる。End of Article

カテゴリ:Windowsフォーム 処理対象:ポップアップ・ヘルプ
使用ライブラリ:Helpクラス(System.Windows.Forms名前空間)
使用ライブラリ:HelpEventArgクラス(System.Windows.Forms名前空間)
関連TIPS:Windowsフォームでポップアップ・ヘルプを表示するには?
関連TIPS:ある座標や領域がコントロールの領域内に含まれているかを確認するには?

この記事と関連性の高い別の.NET TIPS
Windowsフォームでポップアップ・ヘルプを表示するには?
マウス・カーソルの位置を取得・設定するには?
このリストは、(株)デジタルアドバンテージが開発した
自動関連記事探索システム Jigsaw(ジグソー) により自動抽出したものです。
generated by

「.NET TIPS」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間