• ベストアンサー

特定のキーを押すまでループさせるにはどうすればよいですか。

たとえば、ESCキーとか、Qキーを押すまで、一定のことを繰り返し行わせるためには、具体的にどのようなコードを書けばよいでしょうか。 Do While...LoopやDo...Loop Whileを使えばよいのは分かるんですが、キー入力を取ってきて、そのキー入力がESCかどうかの比較をする部分などがよくわかりません。具体的なコードを見せていただけると助かります。 よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.2

いろんなやり方があるかもしれませんが、私ならモジュールレベル変数とか 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を改造する事で、いろんな事が 出来ると思いますよ。

hiyahiya12345
質問者

お礼

フラグを利用ですね。なるほど。 以下のようなコードはあまり良くないですか。 宣言部で Public Declare Function GetAsyncKeyState Lib "user32" (ByVal vKey As Long) As Integer 定義部で Do   (様々な処理。。)   Application.DoEvents() Loop Until GetAsyncKeyState(Keys.Escape)

その他の回答 (2)

回答No.3

ANo.2です。 GetAsyncKeyState ですか… 使った事は無いけど、使って 出来ない事も無さそうな気がしますね。 でも、ちょっと調べてみた感じ、たぶん提示されたコーディングでは あまり宜しくない気がします。 ・GetAsyncKeyState では、「以前にGetAsyncKeyStateが呼ばれたあとの  キー押下」が検知できるみたいなので、Do~Loopの前に一度  呼んでおいた方が良い気がする ・Loop Until GetAsyncKeyState(Keys.Escape) について  ここの条件はBoolean(論理式)として判断できるものでなければ  いけません。  Trueは数値にすると-1なので、-1となる式なら判定に掛かるかも  しれませんが、GetAsyncKeyStateの戻り値は調べて見た感じ、  0~3のような気がする(自信は無い)ので、ビルドに成功したとしても  実際にはずっと条件に引っ掛からないと思います。 上記のあたりだけ何とかすれば、使えなくは ない気がします。 保証は出来ませんが。 …でも、DoEventsを挟むなら、たぶんループの途中でもKeyDownイベントの プロシージャも動いてくれると思うんですが… そうであれば、わざわざ API使うまでもないです。

hiyahiya12345
質問者

お礼

調べてまで頂き、ありがとうございました。教えていただいたことを参考にしながら、もう少しがんばってみます。 >Do~Loopの前に一度呼んでおいた方が良い気がする 特に、上記「なるほど」でした。 ありがとうございました。

  • imogasi
  • ベストアンサー率27% (4737/17069)
回答No.1

>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"の代わりに、実行したいプロシージャ(かプロシージャ名)を書いておけばよい。 初心者のうちは、特にビジネスなどでは、この手のキーインに関連付ける方法は避けて、別の仕組み(メニューやボタンなどか?)にして、この分野に深入りしないほうがよいと思う。

hiyahiya12345
質問者

お礼

教えていただきありがとうございました。OSに捉えさせた方が良いとのこと。わかりました。