Visual Basic 中学校 掲示板 投稿の管理
タグのない投稿を抽出
統計
RSS
Visual Basic 中学校
投稿一覧
拡張メソッドが突然エラーに
この投稿へのリンク
https://keijiban.umayadia.com/ThreadDetail.aspx?ThreadId=30833#CommentId85604
この投稿の削除
削除パスワード
削除する
コメント本文
投稿者
魔界の仮面弁士
 (社会人)
投稿日時
2023/1/21 14:10:31
> ネットで調べてKeyDataというものとKeyCodeというものがあるらしい、というところまでは分かったのですが、それ以上よく分からなかったため、
KeyPress イベントの e.KeyChar は、さほど悩むところでもありませんが、
KeyDown / KeyUp イベントは、ちょっとわかりにくいですよね。
e.KeyCode / e.KeyData に加えて e.KeyValue というものまでありますし…。
まず、同時押しされる『修飾キー』ですが、これは e.Modifiers で得られます。
ここでいう修飾キーとは Ctrlキー、Shiftキー、Altキーの 3 種を
指しており、Windows キーはここに含まれません。
キーボードによっては、修飾キーが左右2か所に配置されることもありますが
複数のキーがあった場合、このイベントでは両者を区別できません。
もしも左右の修飾キー、たとえば LShiftKey と RShiftKey を区別したいような場合には、
ProcessKeyMessage メソッドをオーバーライドすることで調べられます。
修飾キーがどれも押されていなければ、e.Modifiers は Keys.None を返します。
3 種すべての修飾キーがすべて押されている場合には、
If e.Modifiers = (Keys.Shift Or Keys.Control Or Keys.Alt) Then
のように、それぞれをビット Or 加算した値として捉えられます。
あるいは上記と同じ処理を、
If e.Shift AndAlso e.Control AndAlso e.Alt Then
と書くこともできます。
And/Or/AndAlso/OrElse を混同しないように注意してください。
このように、KeyDown や KeyUp であれば e.Modifiers を使って修飾キーを捉えられますが、
KeyPress や MouseDown などには e.Modifiers がありません。しかし、同等機能が
Control クラスにある「ModifierKeys 共有プロパティ」からも得られますので、
If e.Modifiers = (Keys.Shift Or Keys.Control Or Keys.Alt) Then
に相当する処理を
If ModifierKeys = (Keys.Shift Or Keys.Control Or Keys.Alt) Then
と書くこともできます。
なお、文献によっては「Shift キーが押された状態」を
If e.Modifiers.HasFlags(Keys.Shift) Then
If (e.Modifiers And Keys.Shift) = Keys.Shift Then
If (e.Modifiers And Keys.Shift) <> 0 Then
などと記していることもあるのですが、これらの記述法は注意が必要です。
上記はあくまでも Shift キーの状態しか判断していないため、
「Shift」だけでなく、「Ctrl+Shift」「Alt+Shift」「Ctrl+Alt+Shift」の
組み合わせにも反応することになってしまいます。
次は、一番大事な e.KeyCode 。これは、「修飾キー以外」のキーを指します。
また、e.KeyValue は CInt(e.KeyCode) と同義です。
e.KeyCode は物理的なキー位置を示しますので、
CapsLock が On の時の "A" も、CapsLock が Off の時の "a" も、
どちらも Keys.A という同じ情報が返されます。
("A" と "a" を区別する場合は、KeyPress イベントの e.KeyChar を使えます)
そしてこの e.KeyCode ですが……実は修飾キーが単体で押されている場合も
e.KeyCode が Keys.None になることはありません。次のような値になります。
Shift キーが押されている場合は、e.KeyCode = Keys.ShiftKey (Modifiers = Keys.Shift)
Ctrl キーが押されている場合は、e.KeyCode = Keys.ControlKey (Modifiers = Keys.Control)
Alt キーが押されている場合は、e.KeyCode = Keys.Menu (Modifiers = Keys.Alt)
最後は、混乱されていた e.KeyData ですが、
これは e.Modifiers と e.KeyCode のビット OR 演算したものです。
つまり「e.KeyData」と「e.Modifiers Or e.KeyCode」が同じ値になります。
e.KeyData の中から、e.Modifiers の成分だけを取り出す場合には、Keys.Modifiers 値をビット AND 演算します。
つまり「e.KeyData And Keys.Modifiers」と「e.Modifiers」が同じ値になります。
e.KeyData の中から、e.KeyCode の成分だけを取り出す場合には、Keys.KeyCode 値をビット AND 演算します。
つまり「e.KeyData And Keys.KeyCode」と「e.KeyCode」が同じ値になります。
これが、先の回答で『e.KeyData と e.KeyCode の混在利用は不自然』と述べた所以です。
つまり、元のコードでいうところの
> If e.KeyCode = Keys.KeyCode.Alt And e.KeyData = Keys.KeyCode.Enter Then 'Alt + Enter Key
のコードについては、実際には
If e.Modifiers = Keys.Alt AndAlso e.KeyCode = Keys.Enter Then
あるいは
If e.KeyData = (Keys.Alt Or Keys.Return) Then
もしくは
If e.KeyCode = Keys.Enter AndAlso e.Alt AndAlso Not e.Control AndAlso Not e.Shift Then
などと記述します。(どれでも同じ結果が得られます)
結果だけ見れば、元のコードでも同じ結果を得られるのですが、
警告 BC42025 の件と合わせて見直しておかれた方が良いでしょう。