イベントの引数「e」について

タグの編集
投稿者 トマト  (小学生) 投稿日時 2009/8/21 20:15:46
こんにちは。「こんにちは」と打ち込むとIMEの入力候補に「こんにちは根岸」がでてくるトマトです。

今、大発見をしてしまいました。
ボタンなどのClickイベントの引数「e」は、「ByVal e As System.EventArgs」となっているのに、実際はMouseEventArgs型だったり・・・。

ほかにもこのようなイベントがあったら教えてください。
投稿者 usi  (小学生) 投稿日時 2009/8/21 20:31:31
> ほかにもこのようなイベントがあったら教えてください。
範囲が広すぎます♪
投稿者 asd  (社会人) 投稿日時 2009/8/21 20:42:38
>MouseEventArgs型だったり・・・。

http://msdn.microsoft.com/ja-jp/library/system.windows.forms.mouseeventargs.aspx
---以下、引用---
Visual Basic (宣言)

<ComVisibleAttribute(True)> _
Public Class MouseEventArgs _
    Inherits EventArgs
---以上、引用---

継承について調べたらと思います。
投稿者 るしぇ  (社会人) 投稿日時 2009/8/21 20:46:52
あ、かぶった。。。もう継承まで調べちゃった(^^;

まぁ、確かにどう回答すれば良いか困る質問なんですが、
一つの方法として、オブジェクトブラウザで『EventArgs』
という単語を検索してみるとか。

。。。結局、EventArgs を継承してるんですよね。
こういうときにクラスの名前付け規則の重要性が実感できますねぇ。。。

ヘルプでも同じような情報が得られます。
[EventArgs クラス]
http://msdn.microsoft.com/ja-jp/library/system.eventargs.aspx
下のほうに
> 継承階層
ってあるでしょ?これ全部そうです。
もちろん、MouseEventArgs もありますね?

> ほかにもこのようなイベントがあったら教えてください。
上記で上げた引数を使ってるイベントとしか答えられないかなぁ。
例えば、System.Windows.Forms.Splitter.SplitterMoving イベントとか。。。
個々の定義をオブジェクトブラウザやヘルプ(MSDN)で調べていけば
分からないことも無いけど、やってる暇は無いですw
投稿者 るしぇ  (社会人) 投稿日時 2009/8/21 21:04:06
いやいや、質問内容が違った!
> ボタンなどのClickイベントの引数「e」は、「ByVal e As System.EventArgs」となっているのに、実際はMouseEventArgs型だったり・・・。
実際もボタンなどのClickイベントの引数「e」は、「ByVal e As System.EventArgs」です。
MouseClickイベントのほうがMouseEventArgs型です。
Clickイベントでマウスの位置情報なんて無いと思いますが?どうやって検証しました?
投稿者 るしぇ  (社会人) 投稿日時 2009/8/21 21:11:03
うわぁ。。。本当だ。。。
それはそれで不味いだろうと思わないでもない今日この頃。
Pro
    Private Sub Button1_Click(ByVal sender As System.ObjectByVal e As ObjectHandles Button1.Click
        Debug.WriteLine(e.GetType)
    End Sub

[出力結果]
>System.Windows.Forms.MouseEventArgs

> ほかにもこのようなイベントがあったら教えてください。
知らないです。
投稿者 るしぇ  (社会人) 投稿日時 2009/8/21 21:15:05
あ、マウスでクリックしたときは MouseEventArgs でしたが、
キーボードのスペースキーとかEnterキーだと EventArgs でした。

。。。まぁ、そういうことです^^;
投稿者 まだまだ  (中学生) 投稿日時 2009/8/21 21:45:55
こんにちは。
>「こんにちは」と打ち込むとIMEの入力候補に「こんにちは根岸」がでてくるトマトです。
僕は最近Social IMEを使っています。これには予測入力モードがあって、変換候補の思いも寄らない候補が出てきたりしますよ。

なんだか凄いですね(笑)
トマトさんは一体どのようなきっかけで見つけられたのでしょうね?
ルシェさん見たいな方法で遊んでいたら見つかったのでしょうかね.
でもこれって大発見ですよね。
僕も見つけてみようかなとおもいます。
投稿者 トマト  (小学生) 投稿日時 2009/8/21 21:58:52
ウォッチでイベントの引数をみたら、X=??? Y=??? ←覚えてません
のように映っていたので MsgBox(e.GetType.FullName)を実行してみました。
投稿者 るきお  (社会人) 投稿日時 2009/8/21 22:02:45
るしぇさんにすっかり先を越されてしまいました。
私も今回始めて気がつきましたが、確かにマウスでButtonをクリックするとMouseEventArgsが渡されるんですね。VB2005で確認しました。

Private Sub Button1_Click(ByVal sender As System.ObjectByVal e As System.EventArgs) Handles Button1.Click

    Dim mouseE As MouseEventArgs

    mouseE = DirectCast(e, MouseEventArgs)

    MsgBox(mouseE.Location.ToString)

End Sub


でも、るしぇさんご指摘のようにスペースキーなどでクリックした場合は、EventArgsが渡されます。

これを利用してマウスでクリックしたときと、そうでない場合の場合わけを実装して、さらにクリックしたときのマウスの座標を利用してなどと昔なら思ったかもしれませんが、VB2008以降ではButtonにはMouseClickイベントがあるのでClickイベントで頑張る必要はなさそうですね。

他にもイベントの発生の仕方によって引数の型が変わるイベントがあるのではないかと予想しますが、知っているものはないです。

投稿者 るきお  (社会人) 投稿日時 2009/8/21 22:04:24
訂正します。

誤:VB2008以降ではButtonにはMouseClickイベントがあるので
正:VB2005以降ではButtonにはMouseClickイベントがあるので
投稿者 トマト  (小学生) 投稿日時 2009/8/21 22:11:37
もしかして、コントロールをクリックしたときに
'内部イメージ 
Private Sub RaiseMouseClick(ByVal sender As ObjectByVal e As MouseEventArgs) Handles Me.MouseClick
    If e.Button = MouseButtons.Left Then
        OnClick(e)
    End If
End Sub

こんな様な感じになっているのでしょうか?
(さすがにVBでは開発されていないと思いますが)
投稿者 るしぇ  (社会人) 投稿日時 2009/8/21 22:44:21
大発見ですよねぇ。トマトさんの視点はボクも一目置いてます。
同じハンドル名を使い続けている限りチェックさせていただきます。

設計の視点から考えれば納得ですよね。
マウスの処理は MouseClick の処理を共通で使っているんでしょうね。
そこから出力される情報は MouseEventArgs に格納。Click イベントに
流用しているのでしょう。
キーボード入力は当然、別処理で、持ってる情報にマウスの情報が無く、
EventArgs そのまま使ってるんですね。

Click イベント側ではどちらも共通している EventArgs の部分だけ
使うわけです。

継承が有効な場面の例になりますね。

> '内部イメージ 
ボクはクライアント中心の開発者なので、あんまり内部構造を気にした
ことが無いのですが、OSはウィンドウメッセージによる制御をしてますから
メッセージによる単純な分岐じゃないかと思います。
        '内部イメージ 
        If メッセージ = WM_マウスクリック Then
            Dim tmp As MouseEventArgs = New MouseEventArgs(Windows.Forms.MouseButtons.Left, 1, 100, 200, 2)
            RaiseEvent Button1_Click(Button1, tmp)
            RaiseEvent Button1_MouseClick(Button1, tmp)
        End If

        If メッセージ = WM_キーボードクリック Then
            Dim tmp As EventArgs = New EventArgs()
            RaiseEvent Button1_Click(Button1, tmp)
        End If

投稿者 トマト  (社会人) 投稿日時 2009/8/21 23:06:58
メッセージかぁ・・・。
たまに出てくるWM_~ ていうのがMicrosoft流の通信方法の一つなのでしょうか?

まぁ、「イベントの引数の型が違う時はとりあえずEventArgs型にまとめればいいや」という考え方として覚えておきます。(話がかみ合っていなかったらごめんなさい。)

そういえば、るしぇさんのテンションがいつもより高い気がするのですが気のせいでしょうか?
投稿者 るしぇ  (社会人) 投稿日時 2009/8/21 23:33:46
>メッセージかぁ・・・。
http://yokohama.cool.ne.jp/chokuto/win/window.html
http://www.river.sannet.ne.jp/yuui/WinDlg/WinMsg.html

>まぁ、「イベントの引数の型が違う時はとりあえずEventArgs型にまとめればいいや」
実際に使うときでないと目的が見えないから何ともいえないですね。
イベントの引数は VB(=IDE) に自動で書かせればいいので、そのまま使えばいいです。
今回も、Clickイベントの引数「e」は、「ByVal e As System.EventArgs」が自動で
書かれるからそのまま使えばいいんです。

これを逆に MouseEventArgs にしてしまうと、キーボード入力で Click イベントを
起こした時にマウスの情報が足りなくてエラーになります。
誤解を恐れずに言いますと
 マウスのイベント情報 = キーボードのイベント情報 + マウスの情報
だから成り立つということです。
このあたりは「継承」を使いこなせるようにならないと理解は難しいかも?

> そういえば、るしぇさんのテンションがいつもより高い気がするのですが気のせいでしょうか?
え?wそりゃ、質のいい質問が続いているから気分が良い為ですね。
こういう時はサンプルコードとか、普段は出さないノウハウもどんどん出しますよ。

逆にいつもは自分で調べれば1時間(ボクが調べれば10分)くらいで解決しそうな
面白くもなんともない質問ばっかりなのでテンション低いんです。
ボクの場合、気分次第で回答内容は全く変わります。情報を引き出したかったら
質の良い質問をしてテンションを上げるといいですよ。
その後に出した質問には、よっぽどひどくない限り、ほいほい答えますからw
投稿者 トマト  (小学生) 投稿日時 2009/8/22 00:00:08
そういえば、スペースキーでもクリックできるのですね。
はじめて知りました・・・。