C# と VB.NET の質問掲示板

わんくま同盟

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

ツリー一括表示

矢印キーで同時押しを有効にする /花畑 (18/09/05(Wed) 18:21) #88534
Re[1]: 矢印キーで同時押しを有効にする /Hongliang (18/09/05(Wed) 18:42) #88535
Re[1]: 矢印キーで同時押しを有効にする /魔界の仮面弁士 (18/09/05(Wed) 19:15) #88536
  └ Re[2]: 矢印キーで同時押しを有効にする /花畑 (18/09/05(Wed) 19:38) #88537
    └ Re[3]: 矢印キーで同時押しを有効にする /Hongliang (18/09/05(Wed) 20:11) #88538
      └ Re[4]: 矢印キーで同時押しを有効にする /花畑 (18/09/07(Fri) 12:06) #88550
        └ Re[5]: 矢印キーで同時押しを有効にする /魔界の仮面弁士 (18/09/07(Fri) 13:00) #88553
          └ Re[6]: 矢印キーで同時押しを有効にする /花畑 (18/09/07(Fri) 13:07) #88554
            └ Re[7]: 矢印キーで同時押しを有効にする /Hongliang (18/09/07(Fri) 13:16) #88555
              └ Re[8]: 矢印キーで同時押しを有効にする /花畑 (18/09/07(Fri) 14:18) #88556
                └ Re[9]: 矢印キーで同時押しを有効にする /moni (18/09/07(Fri) 14:36) #88557
                  └ Re[10]: 矢印キーで同時押しを有効にする /花畑 (18/09/08(Sat) 19:29) #88577 解決済み


親記事 / ▼[ 88535 ] ▼[ 88536 ]
■88534 / 親階層)  矢印キーで同時押しを有効にする
□投稿者/ 花畑 (1回)-(2018/09/05(Wed) 18:21:18)

分類:[.NET 全般] 

VB.NETを使っていて、矢印キーで操作したいと考えています。

以下のコードで上下右左に関してはうまくいきました。
あと、矢印キーを同時押しした時に斜め方向にも操作できるようにしたいのですが、

            Case Keys.Up Or Keys.Left

とやってみても、うまくいきません。
一体どのように改良すれば良いでしょうか?




    '矢印キーを無効化する
    Private Sub CursorMovementKeys(ByVal sender As Object, ByVal e As KeyEventArgs)

        Select Case e.KeyCode
            Case Keys.Up
                'コード
                e.Handled = True
            Case Keys.Left
                'コード
                e.Handled = True

            Case Keys.Up Or Keys.Left
                'コード
                e.Handled = True

            Case Keys.Right
                'コード
                e.Handled = True
            Case Keys.Down
                'コード
                e.Handled = True
        End Select
    End Sub


[ □ Tree ] 返信 編集キー/

▲[ 88534 ] / 返信無し
■88535 / 1階層)  Re[1]: 矢印キーで同時押しを有効にする
□投稿者/ Hongliang (690回)-(2018/09/05(Wed) 18:42:13)
修飾キー(Shift, Ctrl, Alt)以外の通常キー同士の同時押しを、
WinFormはライブラリとしてはサポートしていません。
Keys列挙体での通常キー同士のOrは不正な値になります。
敢えて書くなら、次のようなコードになるでしょうか。

' 同時押し対象のキーが多いならDictionaryで管理する
Dim m_Up As Boolean, m_Down As Boolean

Sub Form1_KeyDown(...) As Me.KeyDown
  SetKeyState(e.Keycode, True)
  ' 以後、必要な処理
End Sub

Sub Form1_KeyUp(...) As Me.KeyUp
  SetKeyState(e.KeyCode, False)
End Sub

Sub SetKeyState(ByVal key As Keys, ByVal holding As Boolean)
  Select Case e.KeyCode
    Case Keys.Up
      Me.m_Up = holding
    Case Keys.Down
      Me.m_Down = holding
  End Select
End Sub

ちなみに、入力開始時点では、必ずどちらかのキーが先行します。
例え完全に同じタイミングで2つのキーを押下したとしても、
KeyDownは先にどちらかのキーで発生し、その後残りのキーで発生します。

[ 親 88534 / □ Tree ] 返信 編集キー/

▲[ 88534 ] / ▼[ 88537 ]
■88536 / 1階層)  Re[1]: 矢印キーで同時押しを有効にする
□投稿者/ 魔界の仮面弁士 (1817回)-(2018/09/05(Wed) 19:15:55)
No88534 (花畑 さん) に返信
> あと、矢印キーを同時押しした時に斜め方向にも操作できるようにしたいのですが、

Shift, Ctrl, Alt, Win などは同時押しに対応していますが、
それ以外のキーについてはハードウェア依存となりえます。

キーの組み合わせによっては、同時押しができないこともあるのでご注意ください。
https://dailynewsagency.com/2014/03/08/microsoft-applied-sciences-group-bbw/
https://wikiwiki.jp/fpag/%E3%82%AD%E3%83%BC%E3%83%9C%E3%83%BC%E3%83%89%E3%81%AE%E5%90%8C%E6%99%82%E6%8A%BC%E3%81%97%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6
[ 親 88534 / □ Tree ] 返信 編集キー/

▲[ 88536 ] / ▼[ 88538 ]
■88537 / 2階層)  Re[2]: 矢印キーで同時押しを有効にする
□投稿者/ 花畑 (3回)-(2018/09/05(Wed) 19:38:19)
ありがとうございます。

もう一つ質問です。

Shiftキーと通常キーの同時押しを検出するのに
Me.KeyDownメソッドだと、

If Control.ModifierKeys = Keys.Shift Then

を使いますが、

Protected Overrides Function ProcessDialogKey(ByVal keyData As Keys) As Boolean

だとこの方法がうまくいかず、

Case Keys.Shift Or Keys.Up

を使う必要があります。

一方で、逆にMe.KeyDownメソッドだと、

Case Keys.Shift Or Keys.Up

が使えません。

同じ、Keysで宣言された変数なのになぜこのような違いがあるのでしょうか?





[ 親 88534 / □ Tree ] 返信 編集キー/

▲[ 88537 ] / ▼[ 88550 ]
■88538 / 3階層)  Re[3]: 矢印キーで同時押しを有効にする
□投稿者/ Hongliang (691回)-(2018/09/05(Wed) 20:11:57)
> Protected Overrides Function ProcessDialogKey(ByVal keyData As Keys) As Boolean
>
> だとこの方法がうまくいかず、
>
> Case Keys.Shift Or Keys.Up
>
> を使う必要があります。

はて、普通にModifierKeysでも取得できましたが。
ご使用のOS、およびProcessDialogKeyをオーバーライドしている派生元のコントロールは何でしょうか(Form?)。

> 一方で、逆にMe.KeyDownメソッドだと、
>
> Case Keys.Shift Or Keys.Up
>
> が使えません。

e.KeyCodeを使用していませんか?
e.KeyCodeは修飾キーを除いた通常キーのKeys値を返すプロパティです。
修飾キーも含めたKeys値を取得したいのならe.KeyDataプロパティを使用します。
[ 親 88534 / □ Tree ] 返信 編集キー/

▲[ 88538 ] / ▼[ 88553 ]
■88550 / 4階層)  Re[4]: 矢印キーで同時押しを有効にする
□投稿者/ 花畑 (5回)-(2018/09/07(Fri) 12:06:38)

> はて、普通にModifierKeysでも取得できましたが。
> ご使用のOS、およびProcessDialogKeyをオーバーライドしている派生元のコントロールは何でしょうか(Form?)。



再度、試してみましたが、やはりうまくいきませんでした。

OSはWindows10です。

オーバーライドしている派生元のコントロールとはどういうことですか?
フォーム上に、

Protected Overrides Function ProcessDialogKey(ByVal keyData As Keys) As Boolean
End Function

を書いているだけで、どこからも呼び出していません。


If Control.ModifierKeys = Keys.Shift Then コード

というところでは認識できているので、

恐らく、ByVal keyData As Keysを修飾コードを除いたKeyCode形式に変換する必要があるのだと思います。
どのようにすれば形式を変換できますでしょうか?
CTypeを使ってもうまくいきませんでした。



[ 親 88534 / □ Tree ] 返信 編集キー/

▲[ 88550 ] / ▼[ 88554 ]
■88553 / 5階層)  Re[5]: 矢印キーで同時押しを有効にする
□投稿者/ 魔界の仮面弁士 (1824回)-(2018/09/07(Fri) 13:00:49)
2018/09/07(Fri) 13:34:47 編集(投稿者)

No88550 (花畑 さん) に返信
> オーバーライドしている派生元のコントロールとはどういうことですか?
「Overrides Function」をどのクラスに記載しているか、ということです。


> フォーム上に、
> Protected Overrides Function ProcessDialogKey(ByVal keyData As Keys) As Boolean
> End Function
> を書いているだけで、どこからも呼び出していません。
つまりこれは、System.Windows.Foms.Form クラスの ProcessDialogKey クラスを
オーバーライドしている、ということになるわけです。


……ところで、上記のオーバーライド処理は本当に空っぽなのですか?
本来であれば
 Return MyBase.ProcessDialogKey(keyData)
という記述があったはずですが、転記頂いたコードには抜けているので、
常に Return False されてしまうことになるような。


コントロールを何も貼っていないフォームを用意して、

Public Class Form1
 Protected Overrides Function ProcessDialogKey(keyData As Keys) As Boolean
  Debug.WriteLine(keyData.ToString())
  Return MyBase.ProcessDialogKey(keyData)
 End Function
End Class

とした場合、Shift や矢印キーの状態を記録できているか確認してみてください。


> If Control.ModifierKeys = Keys.Shift Then コード
キーボード入力系イベントの引数 e が「そのイベントが呼び出された時のキーの状態」を
表しているのに対し、Control.ModifierKeys は「今現在の押下状態」という違いがあります。

この Control.ModifierKeys というのは、「修飾キーが押されているかどうか」を
調べるための GetKeyState API を呼び出すだけの処理です。
[ 親 88534 / □ Tree ] 返信 編集キー/

▲[ 88553 ] / ▼[ 88555 ]
■88554 / 6階層)  Re[6]: 矢印キーで同時押しを有効にする
□投稿者/ 花畑 (6回)-(2018/09/07(Fri) 13:07:28)
すいません、空っぽなのは、コードを省略して記載したためです。

Protected Overrides Function ProcessDialogKey(ByVal keyData As Keys) As Boolean

のkeyDataは修飾子を含んだキー。

Private Sub CursorMovementKeysDisable(ByVal sender As Object, ByVal e As KeyEventArgs)

のe.KeyCodeは修飾子を含まないキー。
を表すのだと思います。

修飾子を含んだkeyDataから、修飾子に関する情報だけを削除して
e.KeyCodeと同じフォーマットにするにはどのようにしたら良いですか?
[ 親 88534 / □ Tree ] 返信 編集キー/

▲[ 88554 ] / ▼[ 88556 ]
■88555 / 7階層)  Re[7]: 矢印キーで同時押しを有効にする
□投稿者/ Hongliang (693回)-(2018/09/07(Fri) 13:16:39)
> 修飾子を含んだkeyDataから、修飾子に関する情報だけを削除して
> e.KeyCodeと同じフォーマットにするにはどのようにしたら良いですか?

Dim keyCode As Keys = keyData And Keys.KeyCode
[ 親 88534 / □ Tree ] 返信 編集キー/

▲[ 88555 ] / ▼[ 88557 ]
■88556 / 8階層)  Re[8]: 矢印キーで同時押しを有効にする
□投稿者/ 花畑 (8回)-(2018/09/07(Fri) 14:18:02)
ありがとうございます。
うまくいきました。

Orだと二つのキーの足し算で
Andが二つのキーの引き算になるのですね。

何となく逆のような気がしますが。


ところで、TabControlを選択した状態で矢印キーを押すと、隣のページに移る仕様になっていますが、
これを無効化するにはどうしたら良いですか?

TextBoxなどはKeyDownのところで、無効化するコードを書くとうまくいったのですが
TabControlはうまくいきませんでした。

よろしくお願いいたします。
[ 親 88534 / □ Tree ] 返信 編集キー/

▲[ 88556 ] / ▼[ 88577 ]
■88557 / 9階層)  Re[9]: 矢印キーで同時押しを有効にする
□投稿者/ moni (1回)-(2018/09/07(Fri) 14:36:13)
> Orだと二つのキーの足し算で
> Andが二つのキーの引き算になるのですね。
>
> 何となく逆のような気がしますが。

違います。Orは単なる足し算ではないし、Andは引き算でもありません。
ビット演算(ブール代数)を理解する必要があります。
[ 親 88534 / □ Tree ] 返信 編集キー/

▲[ 88557 ] / 返信無し
■88577 / 10階層)  Re[10]: 矢印キーで同時押しを有効にする
□投稿者/ 花畑 (10回)-(2018/09/08(Sat) 19:29:30)
TabControlの矢印キー無効化のこともお聞きしたかったのですが、
最初の質問からそれますので
別で質問させていただきます。
どうもありがとうございます。
解決済み
[ 親 88534 / □ Tree ] 返信 編集キー/


管理者用

- Child Tree -