解説実例で学ぶWindowsプログラミング第4回 操作性を向上させるファンクション・キーへの対応― ユーザビリティを高めるファンクション・バーの実装(後編) ― デジタルアドバンテージ 一色 政彦2005/03/30 |
|
|
■FunctionMenuコントロールの作成
ファンクション・メニューは、前回のファンクション・バーと同じ要領で、クラス・ライブラリ内に作成する。作成時に指定する項目は次のとおりだ。
- ファイル名:「FunctionMenu.cs」
- 名前空間名:「Insiders.Windows.Forms」
- クラス名:「FunctionMenu」
- 継承元クラス:「MainMenuコントロール(System.Windows.Forms名前空間)」
また前回と同様に、Visual Studio .NET(以降、VS.NET)によって生成されたOnPaintメソッドを削除し、さらに次のようにFunctionMenuクラスに対してToolboxBitmap属性を指定しておこう。
[ToolboxBitmap(typeof(MainMenu))]
public FunctionMenu()
これにより、VS.NET IDEのツールボックス上に登録したファンクション・メニューのアイコンが、MainMenuコントロールと同じになる。
■FunctionMenuコントロールへのメニュー項目の追加
次にコントロール内にメニュー項目を追加するわけだが、前回作成したファンクション・バーと違って、IDE(コントロール・デザイナ)の[プロパティ]ウィンドウからは追加できない。これは、メニュー・バーのメニュー項目が([プロパティ]ウィンドウではなく)実際にメニュー・バーを配置したあとのWindowsフォーム・デザイナ上で直接、追加・編集するようになっているためである(ここではまだFunctionMenuコントロールをWindowsフォーム上に配置しているわけではないので、Windowsフォーム・デザイナは開かれていないことに注意)。
従って、手で地道にコーディングするしかないだろう(ちなみに本稿では、すべてを手でコーディングするのではなく、いったん一時的なWindowsフォームを作成してそこにMainMenuコントロールを配置し、そのメニュー・バーをフォーム・デザイナを使って編集し、それにより自動生成されたメニュー・バーに関するソース・コードをコピーして若干の修正を加えたうえで使用した)。
具体的には、次の表に挙げたメニュー項目を作成した。
親項目 |
子項目 |
||||
名前 | テキスト | MergeOrder | 名前 | テキスト | Shortcut |
menuItemOperation | 操作(&O) | 6 … | menuItemF1 | (&1) | F1 |
menuItemF2 | (&2) | F2 | |||
menuItemF3 | (&3) | F3 | |||
menuItemF4 | (&4) | F4 | |||
- | |||||
menuItemF5 | (&5) | F5 | |||
menuItemF6 | (&6) | F6 | |||
menuItemF7 | (&7) | F7 | |||
menuItemF8 | (&8) | F8 | |||
- | |||||
menuItemF9 | (&9) | F9 | |||
menuItemF10 | (&10) | F10 | |||
menuItemF11 | (&11) | F11 | |||
menuItemF12 | (&12) | F12 | |||
- | |||||
menuItemClose | 閉じる(&E) | × … | |||
ファンクション・メニューに追加したメニュー項目 | |||||
メニュー・バーに追加されるメニュー項目の実体は、System.Windows.Forms名前空間のMenuItemオブジェクトである。表中の「名前」は、このオブジェクトの(Name)プロパティ、テキストはTextプロパティ、MergeOrderはMergeOrderプロパティ、ShortcutはShortcutプロパティを意味する。Shortcutの列のデータは、Shortcut列挙体(System.Windows.Forms名前空間)の値を意味し、例えば「F1」は「System.Windows.Forms.Shortcut.F1」を示している。 | |||||
[操作]メニュー項目のMergeOrderプロパティを「6」に設定することで、そのメニュー項目が[業務処理](5)と[ウィンドウ](7)の間に挿入されるようにした。 | |||||
Shortcut列挙体には[Escape]キーが定義されていないため、ショートカット・キーを設定できない(詳細後述)。 |
これを実際にコーディングしたのが、次のFunctionMenu.csのコードだ。
|
|
ファンクション・メニューのメニュー項目の作成 | |
上記コードのInitializeMenuItemsメソッド内では、次の内容が実装されている。
メニュー項目の生成を行う。
メニュー・バーへメニュー項目を追加する。
ファンクション・メニューがMDI親ウィンドウのメニュー・バーの適切な位置にマージされるように、メニュー項目のMergeOrderプロパティを「6」に設定する。
各メニュー項目に対して[F1]〜[F12]キーのShortcutプロパティ(System.Windows.Forms 名前空間MenuItemクラスのプロパティ)を設定している。
メニュー項目とショートカット・キーの関連付け(=[F1]などのショートカット・キーを押すと、該当するメニュー項目の処理が実行されること)は、のShortcutプロパティを設定するだけで実現できる。ただし[Escape]キーは、Shortcutプロパティに設定できないため、ショートカット・キーとの関連付けが、現時点では行われていない。この関連付けについては後述する。
■ファンクション・メニューのテキストや有効状態を切り替えるメソッド
さらに前回のファンクション・バーと同じように、ファンクション・キーに対応したメニュー項目のテキストを変更するためのSetFunctionメソッドと、無効にするためのDisableFunctionメソッドを追加しておこう。
|
|
ファンクション・メニューのメニュー項目設定を行うメソッド | |
前回のファンクション・バーのメソッドとほぼ同じなので説明は割愛する。唯一の違いは、ファンクション・バーのSetFunctionメソッドではその第3パラメータにツールチップに対するテキスト文字列の指定があったが、ファンクション・メニューのSetFunctionメソッドにはこれがない。 | |
■ファンクション・キー入力によるイベント通知の仕組み
メニュー項目がクリックされたときに実行する処理は、それぞれのメニュー項目のClickイベント・ハンドラに実装する。また、ここまでの実装において、メニュー項目のShortcutプロパティが設定されているので、ファンクション・キーが押されたときも、メニュー項目のClickイベントが発行される。要するに、メニュー項目をクリックしたときと、ショートカット・キーを押したときの実行処理は、両方ともClickイベント・ハンドラで一括して実装することができるのだ。
しかしここで1つ問題がある。それぞれのメニュー項目はフォーム上ではなく、FunctionMenuコントロールの中で生成しているので、基本的には、それぞれのメニュー項目のClickイベント・ハンドラも、フォーム上ではなく、そのコントロール内でハンドル(処理)することになる。つまりファンクション・メニューを配置した親フォーム側で、メニュー項目のClickイベントを処理するには何らかの工夫が必要なのだ(なお通常のMainMenuコントロールの利用では、MainMenuコントロールを配置したフォーム内にメニュー項目が生成されるため、そのClickイベントもフォーム内で簡単に処理できる)。
そこで本稿では、次のようにしてこの問題を解決している。
(A)FunctionMenuコントロール内で各メニュー項目のClickイベントを処理する。具体的には、Clickイベント・ハンドラとしてmenuItem_Clickメソッドを追加して、このメソッドによりすべてのメニュー項目のClickイベントをハンドルする。
(B)そのmenuItem_Clickメソッド内で、どのメニュー項目がクリックされたかという情報(=ファンクション・キーの情報)を含む独自のイベント「FunctionKeyPress」を発行する。
(C)フォーム側にこのFunctionKeyPressイベントを処理するイベント・ハンドラを追加する。このイベント・ハンドラ内で、押されたファンクション・キーを判別して適切な処理を行うことになる。
つまり本稿では独自イベントを定義してそれを経由させることで、コントロール内で発生したイベントをフォーム側で処理できるようにしているわけである。このように独自のイベントを利用すれば、柔軟にオブジェクト間(この場合は、コントロール − フォーム間)を連携させられるようになるのである。
(A)と(B)はFunctionMenuコントロール内に実装し、(C)はフォーム側に実装する。まずはFunctionMenuコントロールの実装内容を見てみよう((C)の実装については後述)。
INDEX | ||
解説:実例で学ぶWindowsプログラミング | ||
第4回 操作性を向上させるファンクション・キーへの対応(後編) | ||
1.ファンクション・メニューの実装 | ||
2.FunctionMenuコントロールの作成 | ||
3.独自イベントの実装方法 | ||
4.ファンクション・バーとファンクション・メニューのフォームへの追加 | ||
「解説:実例で学ぶWindowsプログラミング」 |
- 第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用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
|
|
- - PR -