- ベストアンサー
特定のキーを押すまでループさせるにはどうすればよいですか。
たとえば、ESCキーとか、Qキーを押すまで、一定のことを繰り返し行わせるためには、具体的にどのようなコードを書けばよいでしょうか。 Do While...LoopやDo...Loop Whileを使えばよいのは分かるんですが、キー入力を取ってきて、そのキー入力がESCかどうかの比較をする部分などがよくわかりません。具体的なコードを見せていただけると助かります。 よろしくお願いします。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
いろんなやり方があるかもしれませんが、私ならモジュールレベル変数とか Public変数とかの「フラグ」を使って制御しますかね。 以下は、EscapeかQキーを押すまで、ひたすら数値をカウントアップしていく プログラムです。細かいエラー制御とかはしてませんのでご了承を。 あ、VB2005 Expressで書いてます。他のバージョンだと(特にVB6とか) 改造しないと動かない可能性があります。 (今後、バージョンは明記して下さいね…) あと、Do~Loopとかを使うと基本的にフルパワーでループしてしまうので (DoEvents入れたら、フリーズまでは しないですが)、繰り返し処理を している状況をユーザに見せたりする場合は適しませんので、 今回はタイマーを使ってます。 Form1にLabel1、Timer1を貼り付けて、以下のソースを貼り付けてください。 Public Class Form1 '表示用カウンタ Private Counter As Integer = 0 '取得した、特定の入力キー Private InputKey As System.Windows.Forms.Keys = 0 Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load Timer1.Start() End Sub Private Sub Form1_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown '既に入力キーが登録されていれば何もしない If InputKey <> 0 Then Exit Sub Select Case e.KeyCode Case Keys.Q, Keys.Escape '入力キー登録 InputKey = e.KeyCode End Select End Sub Private Sub Timer1_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles Timer1.Tick Select Case InputKey Case Keys.Q, Keys.Escape Timer1.Stop() Exit Sub End Select Counter += 1 Label1.Text = Counter.ToString End Sub End Class 上の例では、InputKeyがフラグの役目を果たします。 InputKey関連の処理を行っているSelect Caseを改造する事で、いろんな事が 出来ると思いますよ。
その他の回答 (2)
- K-Sogacchi
- ベストアンサー率53% (50/93)
ANo.2です。 GetAsyncKeyState ですか… 使った事は無いけど、使って 出来ない事も無さそうな気がしますね。 でも、ちょっと調べてみた感じ、たぶん提示されたコーディングでは あまり宜しくない気がします。 ・GetAsyncKeyState では、「以前にGetAsyncKeyStateが呼ばれたあとの キー押下」が検知できるみたいなので、Do~Loopの前に一度 呼んでおいた方が良い気がする ・Loop Until GetAsyncKeyState(Keys.Escape) について ここの条件はBoolean(論理式)として判断できるものでなければ いけません。 Trueは数値にすると-1なので、-1となる式なら判定に掛かるかも しれませんが、GetAsyncKeyStateの戻り値は調べて見た感じ、 0~3のような気がする(自信は無い)ので、ビルドに成功したとしても 実際にはずっと条件に引っ掛からないと思います。 上記のあたりだけ何とかすれば、使えなくは ない気がします。 保証は出来ませんが。 …でも、DoEventsを挟むなら、たぶんループの途中でもKeyDownイベントの プロシージャも動いてくれると思うんですが… そうであれば、わざわざ API使うまでもないです。
お礼
調べてまで頂き、ありがとうございました。教えていただいたことを参考にしながら、もう少しがんばってみます。 >Do~Loopの前に一度呼んでおいた方が良い気がする 特に、上記「なるほど」でした。 ありがとうございました。
- imogasi
- ベストアンサー率27% (4737/17069)
>Do While...LoopやDo...Loop Whileを使えばよいのは分かるんですが、キー入力を取ってきて、そのキー・・ 勉強(ウインドウズの仕組みの)が十分でないうちの知識で、断定しないこと。奥が深いものだという自戒して勉強が必要。 こういうのは、ユーザーが察知するために、ユーザーのプログラムでループして察知するのでなく、OSというかシステムに捉えてもらい、それをユーザーがもらうというカタチのもので、イベントを捉えてもらうというようなものだ。 (1)本来はAPIを使う分野になるとおもう (2)中途半端だが、旧Basicの時代から、ゲームなどのプログラムのキーインされたキーで処理を分けるために、OnKeyといったステートメントがあった。 その系列なのかVBAにも、Application.OnKey がある。 標準モジュールに Sub auto_Open() Application.OnKey "{Esc}", "test01" End Sub (Auto_Openについて http://www.relief.jp/itnote/archives/001502.php ) Sub test01() MsgBox "aaa" End Sub のようなのを入れて実行(ブックを開く)しておくと、{}内のjキー(この場合エスケープキー)を押すと、この場合aaaが表示される。実際はMsgBox "aaa"の代わりに、実行したいプロシージャ(かプロシージャ名)を書いておけばよい。 初心者のうちは、特にビジネスなどでは、この手のキーインに関連付ける方法は避けて、別の仕組み(メニューやボタンなどか?)にして、この分野に深入りしないほうがよいと思う。
お礼
教えていただきありがとうございました。OSに捉えさせた方が良いとのこと。わかりました。
お礼
フラグを利用ですね。なるほど。 以下のようなコードはあまり良くないですか。 宣言部で Public Declare Function GetAsyncKeyState Lib "user32" (ByVal vKey As Long) As Integer 定義部で Do (様々な処理。。) Application.DoEvents() Loop Until GetAsyncKeyState(Keys.Escape)