質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Win32 API

Win32 APIはMicrosoft Windowsの32bitプロセッサのOSで動作するAPIです。

Q&A

解決済

2回答

2353閲覧

Rubyでキーボードの値を取得(getkeyboardstate)

torisan

総合スコア678

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Win32 API

Win32 APIはMicrosoft Windowsの32bitプロセッサのOSで動作するAPIです。

0グッド

1クリップ

投稿2019/01/23 10:56

編集2019/01/26 01:03

<環境>
Ruby 1.9.3
Windows8

お世話になっています。

Rubyでキーボードの状態の取得を行いたいと思っています。
ほぼキー全体の状態を得たいのでgetkeyboardstateを使用したいと思い
以下のプログラムを作成しました。

Ruby

1 @getkeyboardstate = Win32API.new('user32', 'GetKeyboardState', 'i', 'i') 2 @getkey = [] 3 @getkey.fill(0, 0..255) #256バイト分0で埋める 4 p @getkeyboardstate.call(@getkey[0]) # =>0 5 p @getkey # =>[0,0,0,0,0,0,0..

エラー自体は出ないのですが、4行目の
@getkeyboardstate.call(@getkey[0]) の返り値が0で(正常な場合は0以外の値が返るとの記述を見た)
且つ@getkeyも値の変化が全くない為、
恐らく正常に取得できていないのではないかと考えています。

<試してみた事>
①Win32API の送り値の数を変更。
⇒ArgumentError 1 of 4 のエラーがが出たので、4つで合っていると思われる。
②GetKey**boardState を GetKeyB**oardState にする
⇒そんなものはない、とエラーを返される
③@getkeyboardstate.call(@getkey[0])を@getkeyboardstate.call(@getkey)に
⇒タイプエラー(can't convert Array into String)
④Win32API.new('user32', 'GetKeyboardState', 'i', 'i')の『'』を『"』にする
⇒特に変化なし

そもそもdllの呼び出し方の書き方がおかしいのかと思い、別途GetKeyStateでも試してみました。

Ruby

1 @getkeystate = Win32API.new("user32", "GetKeyState", "i", "i") 2 while true 3 p @getkeystate.call(90) # =>0 か 1 か -127 か -128 4 end

これは(恐らくですが)正常に取得できました。
『z』キー(キーコード:90)を押したり離したりすると、値が変わります。

.
ここからどう手を付ければいいのかわからず、質問に至りました。
Rubyの GetKeyboardState でのキーボードの状態の取得方法、または
別途いい案がありましたら教えて頂けると嬉しいです。

尚、GetKeyStateをループしてゴリ押し、も出来るとは思いますが、なるべく処理を早くしたいため、
GetKeyboardStateのような一括で結果を返す送り値で行えればと思います。

以上、よろしくお願いいたします。


追記:2019/01/24 11:28
VB6で上記と同様と思われるプログラムを作成しました。
こちらは正常に動作します。(返り値に1が返る)

VB6

1Private Declare Function GetKeyboardState Lib "user32" (pbKeyState As Byte) As Long 2 3Private Sub Form_Activate() 4 Dim state(255) As Byte 5 Label1.Caption = GetKeyboardState(state(0)) 'GetKeyboardStateの返り値(1 固定) 6 Label2.Caption = state(90) 'zキーを押した結果(0=>129=>1=>128=>0...) 7End Sub

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

dodox86

2019/01/26 00:54 編集

「Win32 API」タグをつけると回答を得やすくなるはずのご質問です。GetKeyboardStateが使える状況は、アプリの形態に依存します。ウィンドウ(フォーム)ではなく、コンソールアプリでしょうか。
torisan

2019/01/26 01:06

RPGツクールVxAceのスクリプトコマンドに記述しているので、ウィンドウアプリになると思います。
guest

回答2

0

ベストアンサー

1.9.3環境が手元にないので動確できていませんが

ruby

1@getkeyboardstate = Win32API.new('user32', 'GetKeyboardState', 'p', 'i') 2@getkey = "\0" * 256 3@getkeyboardstate.call(@getkey) 4@getkey = @getkey.unpack('C*')

投稿2019/01/26 01:55

asm

総合スコア15147

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

torisan

2019/01/26 10:27

提示のプログラムを試した所、値が返ってきました、ありがとうございます!
guest

0

WinAPI32 に詳しくなく、単なる思いつきなのですが、GetKeybordState の説明がされているサイト(例えば、ここ)を見ると、

BYTE key[256]; GetKeyboardState( key );

となっていて、引数が配列になっています。そこで、試しに
@getkeyboardstate.call(@getkey[0])

@getkeyboardstate.call(@getkey)
にして、引数を配列の先頭の要素にするのではなく、配列そのものにしたらどんなもんでしょうか?
——-
例えば、引数のバッファに書き込む関数を呼び出すには以下のようにします。

Ruby

1api = Win32API.new('foo.dll', 'foo', 'p', 'v') 2buf = "\0" * 256 3api.call(buf)

ポインタの配列を渡す場合は以下のようにします。

Ruby

1api = Win32API.new('foo.dll', 'foo', 'p', 'v') 2args = ["\0" * 256, "\0" * 256, "\0" * 256] 3api.call(args.pack("p3"))

投稿2019/01/23 12:04

編集2019/01/23 13:02
kts_h

総合スコア207

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

torisan

2019/01/23 12:35

質問文には特に変化なしと書きましたが、今行った所TypeErrorとなりました。 can't convert Array into Stringとあるので配列を送り値にする事自体不可能のようです。
kts_h

2019/01/23 12:58

すみません、確認不足でした。代わりと言ってはなんですが、ruby のドキュメントでこんなのを見つけました。 詳しくは、回答の追記で。
torisan

2019/01/23 23:46

追記に関しても試してみましたが、残念ながら特に変化はありませんでした。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問