Visual Basic 初級講座
VB.NET 2002 対応 VB.NET 2003 対応 VB2005 対応

 

Visual Basic 中学校 > 初級講座 >

第21回 マウス・キーボードからの入力

マウス・キーボードから入力をVBで受け取る方法を説明します。右クリックや、マウスホイール、それに[Alt] + [R]のようなキーボード入力が登場します。

この回の要約

・マウス系のイベントをつかうとマウスの動作を捕捉することができる。

・キーボード系のイベントをつかうとキーボード入力を捕捉することができる。

・右クリックはMouseUpイベントで判定する。

・MouseWheelイベントの使用例

・マウスが来たときにラベルを光らせるにはMouseEnterイベントを使う。

・特定のキーの入力をキャンセルにはKeyPressイベントを使う。

・押されたキーの組み合わせを判定するにはKeyDownイベントやKeyUpイベントを使う。

 

1.マウスとキーボード

 

ユーザーがアプリケーションを操作するときはマウスとキーボードを使用します。もちろん、それ以外のケースも考えられますがよほど特殊でなければマウスとキーボードのことだけを考えていれば問題ありません。

マウスとキーボードはアプリケーションを操作する主要な入力装置のため、VBでもこの2つからの入力情報の取得・制御するためにたくさんのイベントが用意されています。

今回はまずマウスから入力情報を取得する方法を説明し、後半はキーボードからの入力情報を取得し、ある程度の制御を行う方法も説明します。どちらも特にVBが配慮しているケースですのでとてもスマートにプログラムの中で利用することができます。

 

2.マウスからの入力

 

マウスからの入力は、基本的にはクリック、ダブルクリック、右クリック、ホイール、カーソルの移動の5種類です。ドラッグ&ドロップはこれらを組み合わせた入力方法でやや複雑です。ドラッグ&ドロップについては次回解説します。

VBではこれらの入力が行われるとイベントが発生します。マウスからの入力により発生するイベントは次の通りです。この表にはドラッグ&ドロップを除いてマウスからの入力により発生するすべてのイベントが記載されています。

イベント 読み方 第2引数の型 概要
Click クリック EventArgs マウスを左クリックしたときに発生します。その他の場合でも発生する場合があります。
DoubleClick ダブルクリック EventArgs マウスを左ダブルクリックしたときに発生します。
MouseClick マウスクリック MouseEventArgs VB2005以降。マウスのどれかのボタンをクリックしたときに発生します。
MouseDown マウスダウン MouseEventArgs マウスのボタンを押したときに発生します。左右中央どのボタンでも発生します。
MouseEnter マウスエンター EventArgs マウスカーソルがコントロールの上に移動してきたときに発生します。
MouseHover マウスホバー EventArgs マウスカーソルがコントロールの上で移動を停止したときに発生します。
MouseLeave マウスリーヴ EventArgs マウスカーソルがコントロールの上から外へ離れていったときに発生します。
MouseMove マウスムーブ MouseEventArgs マウスカーソルがコントロールの上を移動すると発生します。
MouseUp マウスアップ MouseEventArgs 既に押されているマウスのボタンを離したときに発生します。左右中央どのボタンでも発生します。
MouseWheel マウスホイール MouseEventArgs コントロールにフォーカスがあるときにマウスホイールを回転させるとき発生します。

■表1:マウスイベント

この表を見るとわかるのですが、「右クリック」で発生するイベントはありません。右クリックを検知したいときはMouseUpを使 って次のようにプログラムします。

VB.NET 2002 対応 VB.NET 2003 対応 VB2005 対応

Private Sub Form1_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles MyBase.MouseUp

    If e.Button = MouseButtons.Right Then

        MsgBox("右クリックしました!")

    End If

End Sub

■リスト1:右クリックの判定

MouseUpイベントの第2引数を使うとイベントが発生したときのマウスの状態がわかりますからこのようなプログラムが可能です。

VB2005ならば同じことをMouseClickイベントでも行えます。

 

このプログラムでは、MouseEventArgs(読み方:MouseEventArgs = マウスイベントオーグス)のButtonプロパティ(読み方:Button = ボタン)が、MouseButtons.Right(読み方:MouseButtons = マウスボタンズ, Right = ライト)であれば右クリックであると判断しています。

実際にはMouseUpイベントは、既に押されているマウスボタンが離されたときに発生するので、このプログラムの意味は「マウスの右ボタンが離されたら…」という条件になっているわけですが、ボタンを離すと言うことはほとんどクリックと同じ意味になるわけですから右クリックの判定としては問題ありません。もちろん、ボタンが押されたときにMouseDownイベントを利用して右クリックを判断することもできますが、イベントが発生するタイミングがMouseUpMouseDownではことなります。MouseUpで判断する方が自然な操作感があります。

上の表を見るとわかりますが、この他にもMouseMove, MouseWheelでも同じMouseEventArgs型の第2引数を受け取りますので同様の手法でマウスの状態を取得することができます。ただし、イベントの発生のタイミングが異なるのでこれらを右クリックの判定に使うことはできません。

 

3.MouseWheelの使用例

 

以下では、先の紹介したマウスイベントを実際の2つの使用例とともに紹介します。

まず、マウスホイールの回転に合わせて視覚的に量が増減するプログラムを作ってみます。見かけで実感できるちょっと楽しいプログラムですので是非実際に作ってみてください。

MouseWheelの操作を量に置き換えて視覚的に表現する

■画像1:このようにMouseWheelの操作を量に置き換えて視覚的に表現する。

まずフォームにピクチャーボックス(PictureBox)を1つ配置してください。このピクチャーボックスは縦に長く配置します。

そしてピクチャーボックスのプロパティを次のように設定してください。

プロパティ 説明
BackColor Black 背景色を黒にします。
BorderStyle Fixed3D へこませます。

■表2

プログラムは次のようになります。

VB.NET 2002 対応 VB.NET 2003 対応 VB2005 対応

Dim MouseValue As Integer
Private Sub Form1_Activated(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Activated

    PictureBox1.Select()

End Sub

Private Sub PictureBox1_MouseWheel(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseWheel

    '▼ホイールの回転量を元に現在の値を加算する。

    MouseValue += e.Delta

    If MouseValue > 1000 Then '値の最高値を1000に限定する。
       
MouseValue = 1000
    ElseIf MouseValue < 0 Then
'値の最低値を0に限定する。
       
MouseValue = 0
    End
If

    '▼PictureBox1のPaintイベントを呼び出す。

    PictureBox1.Invalidate()

End Sub

Private Sub PictureBox1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles PictureBox1.Paint

    Dim ThisRect As Rectangle

    '▼描画する四角形の座標を計算する。

    ThisRect.Width = PictureBox1.Width '四角形の幅はPictureBox1の幅と同じ。
   
ThisRect.Height = PictureBox1.Height * (MouseValue / 1000) '高さは現在の値に比例
   
ThisRect.X = 0 '行が開始位置の横座標は常に0
   
ThisRect.Y = PictureBox1.Height - ThisRect.Height '描画開始位置の縦座標は高さから計算。

    '▼描画実行。赤い四角形を描画する。

    e.Graphics.FillRectangle(Brushes.Red, ThisRect)

End Sub

■リスト2:MouseWheelの効果を視覚的に表示する

このプログラムはPaintイベント中の座標計算がやや複雑ですが、肝心のMouseWheelイベントは難しくありません。MouseWheelイベントが発生したときにMouseEventArgsDeltaプロパティ(読み方:Delta = デルタ)でホイールの回転量を取得して、変数MouseValueに記録しておきます。そして、PaintイベントでMouseValueの値に応じて赤い四角形を描画するわけです。

ちょっと注意が必要なのはMouseWheelイベントはフォーカスのあるコントロールが受け取るということです。そのためこのプログラムではPictureBox1に強制的にフォーカスを与えるためにフォームのActivatedイベント(読み方:Activated = アクティベイテッド)でPictureBox1Selectメソッドを呼び出しています。Activatedイベントはフォームがアクティブになった直後に発生します。(この場合の「アクティブ」とはユーザーから入力を受け取れるように準備が整った状態を指します。)

途中に出てくる演算子「 += 」は加算を意味しています。MouseValue += e.Delta とは、「現在のMouseValueに値に e.Delta を加えなさい」という意味です。ホイールを下向きに回転させた場合e.Deltaの値はマイナスになるので、実際には加算だけではなく減算も行われます。

この部分は += 演算子を使わないで、 MouseValue = MouseValue + e.Delta と書くこともできます。

PictureBoxInvalidateメソッド(読み方:Invalidate = インバリデイト)は今回はじめて登場しましたが、要はPaintイベントを呼び出しているだけです。PatinイベントはWindowsが描画必要と判断した場合には自動で呼び出されますが、そうでない限りはInvalidateメソッド等を使って自分で呼び出す必要があります。

 

4.マウスが来ると光るラベル

 

次に、マウスが来ると光るラベルを作ります。今度の例はイベントを素直に使うだけの簡単なものです。

まず、フォームにラベルを1つ貼り付けて次の通りプロパティを設定してください。

プロパティ 説明
BackColor Black 背景色を黒にします。
BorderStyle Fixed3D へこませます。
Font サイズ16, 太字 文字を大きくします。
ForeColor Chocolate 文字の色をチョコレート色にします。
Text Mouse Test  
TextAlign MiddleCenter 文字をラベルの中央に表示します。

■表3

プログラムは次の通りです。

VB.NET 2002 対応 VB.NET 2003 対応 VB2005 対応

Private Sub Label1_MouseEnter(ByVal sender As Object, ByVal e As System.EventArgs) Handles Label1.MouseEnter

    Label1.BackColor = Color.LawnGreen

End Sub

Private Sub Label1_MouseLeave(ByVal sender As Object, ByVal e As System.EventArgs) Handles Label1.MouseLeave

    Label1.BackColor = Color.Black
    Label1.Text = "Mouse Test"

End Sub

Private Sub Label1_MouseHover(ByVal sender As Object, ByVal e As System.EventArgs) Handles Label1.MouseHover

    Label1.Text = "●HOVER●"

End Sub

■リスト3

このプログラムは単純なので解説の必要はほとんどありません。実行するとどうなるかは実際に試してみてください。

 

5.クリックしなくても発生するClickイベント

 

さて、マウスイベントの最後にClickイベントについて簡単に注意を書いておきます。

Clickイベントはクリックしなくても発生する場合があります。たとえば、チェックボックスやラジオボタンにフォーカスがあるときに[スペース]キーを押すとクリックイベントが発生します。 また、ボタンにフォーカスがあるときに[ENTER]キーを押してもクリックイベントが発生します。他にもマウスのクリック以外でClickイベントが発生する場合があるようです。

なぜこのような仕様なのかはわかりません。VB6時代からの伝統でしょうか?

とはいっても普通に使っている限りこの仕様で特に困ることはありません。むしろ便利です。どうしても、マウスでクリックしたときだけに反応したい場合はMouseClickイベントを使います。ただし、MouseClickイベントはVB2005以降でないと使えません。

 

6.キーボードからの入力

 

キーボードからの入力のために使うイベントは3つしかありません。マウスと違って「移動」という操作がないからです。キーボードからの入力では「どのキーが押されたか」という情報が最も重要です。また、[Ctrl] + [C] や [Alt] + [Enter]などのように押されたキーの組み合わせが重要な場合もあります。

イベント 読み方 第2引数の型 概要
KeyDown キーダウン KeyEventArgs キーを押したときに発生します。
KeyPress キープレス KeyPressEventArgs キーボードから文字キーを入力したときに発生します。
KeyUp キーアップ KeyEventArgs 既に押されているキーを離したときに発生します。

■表4:キーボードイベント

 

7.KeyPressイベントの詳細

 

KeyDownイベントとKeyUpイベントはどのキーが押されたときでも発生するのですが、KeyPressイベントは「文字キー」が押されたときにしか発生しません。この辺りの事情が初心者にはわかりにくくなっています。

「文字キー」というのは今、私が便宜のために勝手に使っている言葉ですが、要するに文字のキーです。たとえば、[A], [B], [C]です。

一方、文字のキーではない[F1], [SHIFT], [DELETE]などではKeyPressイベントは発生しません。

ここまでは単純に切り分けられるので理解もしやすいのですが、複雑なのはここからです。[ESC], [スペース], [ENTER], [BackSpace]は例外的にKeyPressイベントが発生します。

[スペース]や[ENTER]はまだしも、[BackSpace]ではKeyPressイベントが発生するのに、[DELETE]ではKeyPressイベントが発生しないなどはっきりいって知らなきゃわかりません。きっと昔からのパソコン・環境の仕様との関連で現在もこのような仕様になっているのでしょう。

KeyPressイベントを使って押されたキーを判断するにはKeyPressEventArgs型(読み方:KeyPressEventArgs = キープレスイベントオーグス)の第2引数のKeyCharプロパティ(読み方:KeyChar = キーキャラ)を使います。

VB.NET 2002 対応 VB.NET 2003 対応 VB2005 対応

Private Sub TextBox1_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles TextBox1.KeyPress

    ListBox1.Items.Add(e.KeyChar)

End Sub

■リスト4:入力された文字をリストボックスにも表示する

この例では、入力された文字をリストボックスにも追加していきます。KeyPressイベントの動作を実験するのにはちょうどよいプログラムです。たとえば、IMEで漢字変換したときにKeyPressイベントがどのように反応するかは知っておいて損はありません。

結論を言うとIMEで漢字変換などの日本語編集中はキーボード関連のイベントは発生しません。この場合は変換を確定した瞬間にイベントが発生します。そのときにはKeyCharプロパティは押されたキーボードのキーの文字ではなく、変換後の文字がセットされています。

なお、KeyPressEventArgsHandledプロパティ(読み方:Handled = ハンドルド)にTrueをセットすることによりキーが処理済であることを.NET Frameworkに通知することができます。この通知がなされると本来の自動的に行われる処理が行われなくなります。

たとえば、次のプログラムでは入力した文字がリストボックスには表示されますが、肝心のテキストボックスには表示されなくなります。

VB.NET 2002 対応 VB.NET 2003 対応 VB2005 対応

Private Sub TextBox1_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles TextBox1.KeyPress

    ListBox1.Items.Add(e.KeyChar)

    e.Handled = True

End Sub

■リスト5

でも、VB.NET2002およびVB.NET2003ではIMEによる日本語入力はテキストボックスにも表示されます。多分、IMEによる日本語入力は .NET Framework 1.1によるキーボード処理とは違う経路をたどっているのでしょう。もし、プログラムで日本語入力まで詳細に制御しようとするならば相当の苦労を強いられることでしょう。

VB2005では、リスト5のプログラムで日本語入力もきちんと処理することができます。

Handledプロパティを使うと特定の文字の入力を禁止することもできます。

次の例はテキストボックスに "P" を入力できなくします。"p"は入力できます。

VB.NET 2002 対応 VB.NET 2003 対応 VB2005 対応

Private Sub TextBox1_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles TextBox1.KeyPress

    If e.KeyChar = "P" Then
        e.Handled = True
   
End If

End Sub

■リスト6:"P"の入力をキャンセルする。

でもやはりVB.NET2002およびVB.NET2003ではIMEの日本語入力を使うと半角のPを入力できてしまいます…。テキストボックスのIMEModeプロパティ(読み方:IMEMode = アイエムイーモード)をDisable(読み方:Disable = ディスエイブル)にするとIMEが使用不可になりますのでこの問題を回避できますが、すべての全角文字が入力できなくなるというデメリットもあります。

VB2005では、IMEの日本語入力使ったとしても"P"の入力を完全にキャンセルすることができます。

ただし、どのバージョンのVBであってもKeyPressイベントでは「貼り付け」を防げない点には注意してください。つまり、メモ帳か何かから"P"と言う字をコピーして、このテキストボックスに貼り付けることはできます。

まぁVB.NET2003以前のバージョンでは文字の入力自体を細かく制御することはできるだけ避けた方が良さそうです。それでも、どうしても"P"が許せない場合はValidatingイベント(読み方:Validating = バリデイティング)を使って入力のチェックを行うことになります。このイベントはKeyPressイベントと違って素直に動作してくれて使いやすいのでお勧めです。このイベントについては次々回で説明する予定です。

 

8.KeyDownとKeyUp

 

最後に残されたKeyDownKeyUpについて説明します。この2つはKeyPressではドラップできない[F1]、 [Shift]などのキーの検出に使います。また、KeyPressイベントはキーを押したときに1回だけ発生するのに対して、KeyDownイベントとKeyUpイベントを組み合わせるとキーが現在押しっぱなしになっているかどうかを判断することもできます。

KeyDownイベントもKeyUpイベントも文字に着目しているKeyPressイベントとは異なり、キーボードのキーに着目します。たとえば、この2つのイベントでは"A"も"a"も同じ意味になります。

この2つのイベントの第2引数のKeyEventArgs型は以前のバージョンのVBにくらべて大変親切になっているのですぐに使い方がわかります。代表的なプロパティをまとめると次の通りです。

プロパティ 読み方 説明
Alt オルト イベントが発生したときに[Alt]キーが押されていたかを示します。
Control コントロール イベントが発生したときに[Ctl]キーが押されていたかを示します。
KeyCode キーコード 押されたキーのコードを示します。
Shift シフト イベントが発生したときに「Shift]キーが押されていたかを示します。

■表5

これらを使うと簡単に押されたキーの情報を取得します。

次のプログラムでは[Alt] + [R] を押すとフォームの背景を赤にします。 [Shift] + [Alt] + [R]を押すと元の色に戻します。

VB.NET 2002 対応 VB.NET 2003 対応 VB2005 対応

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

    'フォームでキーボードイベントを認識するにはKeyPreview = True にする。
   
Me.KeyPreview = True

End Sub

Private Sub Form1_KeyUp(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles MyBase.KeyUp

    If e.KeyCode = Keys.R Then
       
If e.Alt And e.Shift Then
           
'[Shift] + [Alt] + [R] でフォームの色を元に戻す。
           
Me.BackColor = Color.FromKnownColor(KnownColor.Control)
        ElseIf e.Alt
Then
           
'[Alt] + [R] でフォームの色を赤にする。
           
Me.BackColor = Color.Red
        End
If
   
End If

End Sub

■リスト7

この例からもわかるようにKeyCodeプロパティを使って押されたキーを判定するにはKeys列挙体(読み方:Keys = キーズ)を使用します。これはVBで色を表すときにColor.RedColor.Blackなどと書くことができるのと同様に手軽にKeys.RKeys.Enterなどと書くことができます。文字以外の代表的な制御キーがKeys列挙体でどのように表現されるかを参考のため表にしておきます。

キーボード Keys列挙体の値
[ESC] Escape
[F1], [F2], ... F1, F2, ...
[Enter] Enter
[←], [↑], [→], [↓] Left, Up, Down, Right
キーボードの[1], [2], [3], ... D1, D2, D3, ...
テンキーの[1], [2], [3], ... NumPad1, NumPad2, NumPad2, ...

■表6

このほかにもさまざまな制御キーを判定することができます。詳細はMSDNライブラリをご覧下さい。

中にも見たことも聞いたこともない外国用の制御キーもあります。