解説

実例で学ぶWindowsプログラミング

第4回 操作性を向上させるファンクション・キーへの対応

― ユーザビリティを高めるファンクション・バーの実装(後編) ―

デジタルアドバンテージ 一色 政彦
2005/03/30
Page1 Page2 Page3 Page4

■独自イベントの実装方法

 独自のイベントを実装するには、基本的に次の5つの宣言と処理と定義が必要だ。

(1)イベント・ハンドラを登録するためのデリゲートの宣言
(2)イベント変数の宣言
(3)イベント・ハンドラに渡すイベント引数の生成
(4)イベント・ハンドラの呼び出し(=イベントの発行)
(5)イベント引数の定義

 具体的なコード内容を下に示す(これらのイベントの実装内容は細かく説明しないので、コード中のコメントを参考にしてほしい)。なお、より詳しいイベントの実装方法については、「改訂版 C#入門」の「第17章 言語に内蔵されたイベント機能」や「改訂版 プロフェッショナルVB.NETプログラミング」の「Chapter 12 イベント」を参照していただきたい。

[ToolboxBitmap(typeof(MainMenu)), DefaultEvent("FunctionKeyPress")]
public class FunctionMenu : System.Windows.Forms.MainMenu
{
  // ファンクション・キー押し下げイベント
  // (1)イベント・ハンドラを登録するためのデリゲートの宣言
  public delegate void onFunctionKeyPress(object sender, FunctionKeyPressEventArgs e);
  // (2)イベント変数の宣言
  [Category("アクション")]
  public event onFunctionKeyPress FunctionKeyPress;
 
      ……中略……

  // (A)ファンクション・メニュー項目のクリック処理を行う
  private void menuItem_Click(object sender, System.EventArgs e)
  {
    if (FunctionKeyPress != null)
    {
      FunctionKey id;
      if (sender.Equals(this.menuItemF1))
      {
        id = FunctionKey.F1;
      }
      else if (sender.Equals(this.menuItemF2))
      ……中略……

      // (B)FunctionKeyPressイベントを発行する

      // (3)イベント・ハンドラに渡すイベント引数の生成
      FunctionKeyPressEventArgs arg = new FunctionKeyPressEventArgs(id);
      // (4)イベント・ハンドラの呼び出し(=イベントの発行)
      FunctionKeyPress(this, arg);
    }
  }
}

// (5)イベント引数の定義
public class FunctionKeyPressEventArgs : EventArgs
{
  public FunctionKeyPressEventArgs(FunctionKey key)
  {
    this.key = key;
  }

  public FunctionKey FunctionKey
  {
    get
    {
      return this.key;
    }
  }
  private readonly FunctionKey key;
}
FunctionKeyPress(ファンクション・キー押し下げ)イベントの通知機能

 上記コードで注目してほしい部分は、FunctionMenuクラスに対して「DefaultEvent("FunctionKeyPress")」という属性を設定しているところだ。この属性設定を行っておけば、フォーム・デザイナ上に表示されたFunctionMenuコントロール(デザイナ下部のコンポーネント領域に表示される)をダブルクリックするだけで、自動的にFunctionKeyPressイベント・ハンドラを追加できるようになるので非常に便利だ(この作業については後で紹介する)。

■そのほかに実装されているメソッド

 FunctionMenuクラスでは、上記の実装以外に、次のようなメソッドも実装されている。

// 指定されたファンクション・メニューのクリック動作を行う
public void PerformClick(string functionName);

// Escapeキーを処理する
public static bool ProcessEscapeKey(Form active);
ファンクション・メニューで実装されているそのほかのメソッド

 PerformClickメソッドは、ファンクション・メニューのメニュー項目のクリックをシミュレートするためのものだ。PerformClickメソッドのfunctionNameパラメータには、“F1”“Escape”などのファンクション・キーのタグ文字列を指定するが、要するにこのパラメータに指定したタグ文字列(ファンクション・キー)に該当するメニュー項目のクリック動作がシミュレートされる。なおこのタグ文字列とは前回のファンクション・バーのボタンに設定したTagプロパティの文字列のことである。

 このPerformClickメソッドは、ファンクション・バーのボタンがクリックされたときにファンクション・メニューのメニュー項目のクリックをシミュレートし、その結果、ファンクション・メニューのClickイベントが発行されて、先ほどのFunctionKeyPressイベントの発行にたどり着く。これにより最終的には、ファンクション・バーとファンクション・メニューの処理を、FunctionKeyPressイベント・ハンドラで一元管理できるようになるわけである(フォーム側の実装内容は後述する)。

FunctionKeyPressイベント・ハンドラによるファンクション処理の一元管理

 またProcessEscapeKeyメソッドは、(先ほど述べたように)メニュー・バーのショートカット・キー機能(Shortcut列挙体)が[Escape]キーに対応していないので、その機能を補助するために用意したメソッドだ。具体的には、MDI親フォームのProcessDialogKeyメソッド内で、処理中のキーが[Escape]であればパラメータに現在アクティブなフォームを指定してこのProcessEscapeKeyメソッドを呼び出す。

 このProcessEscapeKeyメソッド内では、アクティブなフォームがファンクション・メニューを持つMDI子ウィンドウかどうかをチェックし、もしそうならば、パラメータに“Escape”というタグ文字列を指定して(先ほど示した)ファンクション・メニューのPerformClickメソッドを実行する。これにより、該当のコントロール内で[Escape]キーに関するClickイベントが発生し、最終的にフォームなどに対してFunctionKeyPressイベントが発行される。要するに、このProcessEscapeKeyメソッドを使うことで、すべてのファンクション・キーの処理が可能になるわけである。

 以上でファンクション・メニューの実装は完了だ。

■ファンクション・バーとファンクション・メニューの一括設定クラス

 後はこのファンクション・メニューや前回作成したファンクション・バーを実際にフォーム上に配置していくわけだが、これらには、どちらもボタンやメニュー項目の設定を変更するためのSetFunctionメソッドとDisableFunctionメソッドが実装されている。これらのメソッドの呼び出し内容は共通しているので、できれば1回の呼び出しでファンクション・バーとファンクション・メニューの両方を一度に設定してしまいたい。

 そこで本稿では、次のようなヘルパー・クラス(FunctionManager)を作成した(コード内容の詳細は割愛するが、そのメソッドの定義内容を示しておく)。

public class FunctionManager
{
  // ファンクション・バーとファンクション・メニューを指定するコンストラクタ
  public FunctionManager(FunctionMenu newMenu, FunctionBar newBar);

  // 指定されたファンクションの設定を変更し、有効にする
  public void SetFunction(FunctionKey key, string setText, string setToolTipText);

  // 指定されたファンクションを無効にする
  public void DisableFunction(params FunctionKey[] keys);
}
ファンクション・メニューのメニュー項目設定を行うメソッド

 それではここまでに作成したファンクション・バーとファンクション・メニューをフォーム上に貼り付けて使ってみよう。なお作成したコントロールは、事前にVS.NET IDEのツールボックスへ登録しておくことをお忘れなく。その方法は、第2回で解説している。


 INDEX
  解説:実例で学ぶWindowsプログラミング
  第4回 操作性を向上させるファンクション・キーへの対応(後編)
    1.ファンクション・メニューの実装
    2.FunctionMenuコントロールの作成
  3.独自イベントの実装方法
    4.ファンクション・バーとファンクション・メニューのフォームへの追加
 
インデックス・ページヘ  「解説:実例で学ぶWindowsプログラミング」


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メールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)
- PR -

注目のテーマ

業務アプリInsider 記事ランキング

本日 月間
ソリューションFLASH