前章では、右クリックで出てくるコンテキスト・メニューをやりました。この章では、どのボタンを押しても出てくるメニューを作ります。
はっきり言って邪道です。
しかし、C#のプログラミングの仕組みを知る上では多少は役立つかもしれません。
クライアント領域でマウスがクリック(どのボタンでもよい)されると、MouseDownイベントが発生します。これを捕まえればよいですね。
では、コンテキストメニューを表示するにはどうすればよいでしょうか。
これには、ContextMenuクラスのShowメソッドを使います。
public void Show ( Control control, Point pos ) public void Show ( Control control, Point pos, LeftRightAlignment alignment )2つのオーバーロード・バージョンがあります。
controlは、メニューを関連づけるControlを指定します。
posには、メニューを表示するPointを指定します。
alignmentには、オブジェクトがPointの左、右どちらに配置されるかを指定します。
LeftRightAlignment列挙体のメンバは、次の通りです。
| メンバ | 意味 | 
|---|---|
| Left | オブジェクトが参照ポイントの左側に配置 | 
| Right | 右側に配置 | 
さて、マウスのボタンが押された座標はどうすればわかるのでしょうか。 これには、MouseDownイベントに関連づけられたControl.OnMouseDownメソッドの引数を調べるとわかります。
protected virtual void OnMouseDown ( MouseEventArgs e )このメソッドを、オーバーライドするとMouseDownイベントの処理ができます。
MouseEventArgsクラスのX,Yプロパティがマウスイベント発生時のX,Y座標です。また、 Buttonプロパティは、どのボタンが押されたかを表します。
public MouseButtons Button { get; }
MouseButtons列挙体のメンバと意味は次の通りです。
| メンバ | 意味 | 
|---|---|
| Left | マウスの左ボタンが押された | 
| Middle | 中央ボタン(ホィール)が押された | 
| None | ボタンは押されていない | 
| Right | 右ボタンが押された | 
| XButton1 | 1番目のXButtonが押された | 
| XButton2 | 2番目のXButtonが押された | 
Xボタンというのは、マウスの側面についていて、通常ブラウザの「進む」「戻る」の機能が割り振られています。
では、サンプルを見てみましょう。いずれかのボタンが押されると、メニューが出現します。また、クライアント領域にどのボタンが押されたかが表示されます。
// contextmenu02.cs
using System;
using System.Drawing;
using System.Windows.Forms;
class contextmenu02 : Form
{
    ContextMenu cm;
    string str;
    public static void Main()
    {
        contextmenu02 c2 = new contextmenu02();
        Application.Run(c2);
    }
    // コンストラクタ
    public contextmenu02()
    {
        Text = "猫でもわかるC#";
        BackColor = SystemColors.Window;
        cm = new ContextMenu();
        //ContextMenu = cm;
        //ContextMenuプロパティにcmを設定していない!!
        MenuItem miFile = new MenuItem("ファイル(&F)");
        cm.MenuItems.Add(miFile);
        MenuItem miExit = new MenuItem("終了(&X)");
        miExit.Click += new EventHandler(miExit_Click);
        miFile.MenuItems.Add(miExit);
    }
    // メニューの「終了」が選択された
    void miExit_Click(object sender, EventArgs e)
    {
        Close();   
    }
    // Paintイベントが発生した
    protected override void OnPaint(PaintEventArgs e)
    {
        base.OnPaint(e);
        Graphics g = e.Graphics;
        Font f = new Font("MS ゴシック", 16);
        g.DrawString(str, f, Brushes.Black, new PointF(10F, 10F)); 
    }
    // FormClosingイベントが発生した
    protected override void OnFormClosing(FormClosingEventArgs e)
    {
        base.OnFormClosing(e);
        DialogResult dr;
        dr = MessageBox.Show("終了してもよいですか",
            "猫C#",
            MessageBoxButtons.YesNo,
            MessageBoxIcon.Question);
        if (dr == DialogResult.Yes)
            e.Cancel = false;
        else
            e.Cancel = true;
    }
    // マウスボタン(どのボタンでもよい)が押下された
    protected override void OnMouseDown(MouseEventArgs e)
    {
        base.OnMouseDown(e);
        if (e.Button == MouseButtons.Left)
            str = "左ボタンが押されました";
        else if (e.Button == MouseButtons.Right)
            str = "右ボタンが押されました";
        else if (e.Button == MouseButtons.Middle)
            str = "ホィールが押されました";
        else
            str = "その他のボタンが押されました";
        // Paintイベントを発生させてstrをクライアント領域に再描画
        Invalidate();
        cm.Show(this, new Point(e.X, e.Y));
    }
}
コメントを見ながら、プログラムを眺めていくと大して難しくないことがわかりますね。
Update 08/Nov/2006 By Y.Kumei