VB6 SP6 でプログラムを作成しています。
コマンドボタンが押されているか、調べるには、どのようにすれば良いのでしょうか?
Value プロパティを Timer の中で調べるようにプログラムしてみたのですが、
ボタンを押してもValueプロパティがTrue になりません。
ご存知の方、宜しくお願いします。
ボタンの KeyDown イベントで vbKeySpace の時と、MouseDown イベントでフラグを立てて、
KeyUp イベントと MouseUp イベントでフラグを解除すると、
フラグの立ってる間がボタンが押されていると判断できるのでは?
>Value プロパティを Timer の中で調べるようにプログラムしてみたのですが
Command2 のクリックイベントで
Command1.Value = True
とか書くと、Command1_Click が起こる。。。というような使い方をします。。。
Value プロパティのヘルプに
>ボタンが選択されているかいないかを示す値を設定します。値の取得も可能です。
と書いてあったので、テストしてみました。
[VB6.0 sp5]
Private Sub Command1_Click()
Debug.Print Now & ":" & Command1.Value
End Sub
Private Sub Form_Load()
Me.Timer1.Interval = 1000
End Sub
Private Sub Timer1_Timer()
Debug.Print Now & ":" & Command1.Value & "[Timer]"
End Sub
>2007/07/06 10:49:26:True
>2007/07/06 10:49:26:False[Timer]
確かにクリックイベント内では True になっていますが、押しっぱなしにしても
True は継続されないようです。。。
・Microsoft Windows CE Toolkit for Visual Basic 6.0
・Microsoft Windows CE Toolkit for Visual Basic 5.0
ではフォーカスが当たっただけで True になるようですし。。。
http://support.microsoft.com/kb/180762/ja
特攻隊長まるるうさん。
色々ありがとうございます。
今回やりたいのは、コマンドボタンが押されている間、
モータを回す(JOG動作)という事を行いたいのですが、
コマンドボタンを連打されると、なぜかMouseUpイベントが起きず、
モータが止まらないという現象が起きてしまいます。
(MouseDown イベントでモータを回す処理をし、MouseUpイベントでモータを止める処理
を行っています。)
そこで、TimerでコマンドボタンのValue を調べて押されていなかったら
モータを止める処理をしようと思ったのですが。。。
もう少し考えてみます。
>コマンドボタンを連打されると、なぜかMouseUpイベントが起きず、
そっちの原因を突き止めないと安定した動作にはならないのでは?
・DoEvents は入れていないですか?
・Enebled の変更をしてますか?
これらの命令は、よく使われている割に使用が難しく、適切な場所に
入れないとバグを生みます。
具体的なサンプルコードを示して質問したほうが良いのでは?
特攻隊長まるるう様
ありがとうございます。
下記のようにコーディングしています。
Private Sub CmdXYDW_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
Debug.Print "押された"
If Button = 2 Then Exit Sub
if 処理中=1 then Exit Sub
処理中=1
Motor駆動処理
|
|
|
End Sub
Private Sub CmdXYDW_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single)
Debug.Print "Y_DW はなされた"
Motor停止処理
|
|
|
処理中=0
End Sub
このプログラムだと、コマンドボタンが押されてモータ駆動の処理が
始まり、その途中で又、コマンドボタンが押されると又、モータ駆動処理
が始まってしまっているようです。
コマンドボタンが押された時、EnableをFalse にしてしまうと
MouseUp Eventが起きなくなってしまいます。
処理が終わるまで、コマンドボタンの入力を禁止する方法があるといいのですが。
宜しくお願いします。
いっそCommandじゃなくてCheckにして、押しっぱなしではなくボタンの状態で判断しては如何でしょうか
Motor駆動処理に時間がかかる為、早押しした時MouseUpにすぐに処理が戻らないのでしょう。
2つ問題があって、一つは時間が掛かるMotor駆動処理の中にDoEventsを入れることが出来て、
Windowsに処理が戻せるかと言う点と、Motor駆動処理中にMouseUpがなされた時、処理を直ちに
終了できるかと言うことです。
いずれにしろこの点はブラックボックスとなっていて、アドバイスは出来ません。
Motor駆動処理がMotorOnなどというDll呼び出しになっている場合は、モーターのレスポンスが
悪いと言うことで、軽いJog動作は諦めるしかありません。
JOG動作と聞くとわたしの仕事でも聞く単語なので参考にでもなれば。
(VBでJOG動作のソフトは作ってはいないですけどね)
まず確認しておきたいのは、連打したときにMouseDownとMouseUpの数の回数が一致しない、ということですか?
それとも回数が一致しているのにモーターが停止しないということでしょうか?
もし後者であれば、Motor駆動処理(むしろ起動処理)が完了する前にMouseUpイベントがおきて、実質的にMotor停止処理が終わった後にMotor駆動処理が行われている可能性があるのではないでしょうか。
ひとつの案として、MouseUpイベントでStopFlagを立てることにしておき、
Motor駆動処理をStopFlagがTrueになるまでループするという方法はどうでしょうか。
ただし、MouseDownとMouseUpの数の回数が一致していることが前提となりますが。
Sub JOG+ボタンMouseUpイベント
StopFlag = True
End Sub
Sub JOG+ボタンMouseDownイベント
モーター起動処理
Do Until StopFlag
DoEvents
Sleep(1)
Loop
モーター停止処理
StopFlag = False
End Sub
また、同じモーターに対して+方向のJOG動作と−方向のJOG動作がある場合も同じような問題が出ることが考えられます。
(まぁ、複数のボタンをそんなにすばやく押し替えれる人もいないでしょうが)
ということも考慮して、もうひとつの案です。
(勝手にJOG動作に+と−があることにしてみたり)
Sub JOG+ボタンMouseDownイベント
pJOGFlag = True
End Sub
Sub JOG+ボタンMouseUpイベント
pJOGFlag = False
StopFlag = True
End Sub
Sub JOG−ボタンMouseDownイベント
mJOGFlag=True
End Sub
Sub JOG−ボタンMouseUpイベント
mJOGFlag = False
StopFlag = True
End Sub
Sub インターバルタイマーTimmerイベント
Select Case True
Case StopFlag
モーター停止処理
StopFlag = False
Case pJOGFlag
モーター正方向起動処理
pJOGFlag = False
Case mJOGFlag
モーター負方向起動処理
mJOGFlag = False
End Select
End Sub
インターバルタイマーは0.1秒周期で事足りるでしょう。
(VBで0.05秒周期より短くするのは怖いです)
タイマーを常時動かしておくのが気分悪いというなら、JOG操作マスタボタンを追加して以下のようにするのもいいのでは。
Sub JOG操作マスタボタンClickイベント
If JOG操作マスタ.BackColor <> vbButtonFace Then
JOG操作マスタ.BackColor = vbButtonFace
インターバルタイマー.Enabled = False
モーター停止処理 'もしものときの保険
Else
JOG操作マスタ.BackColor = vbRed
インターバルタイマー.Enabled = True
End If
pJOGFlag = False
mJOGFlag = False
StopFlag = False
End Sub
ここにインチング動作やポジション移動動作が加わるとStopFlag以外のFlagをBoolean型以外にしたほうがいいかもしれませんけどね。
多少突っ込みどころもありますが、わたしならこうします。
なんにしろモーターがパソコンで直接制御されている場合もあれば、通信でやり取りする場合(ラグが多い)もあると思うので、モーターが動きっぱなしは危険ですよね。
「コマンドボタンが押されているかを調べる」ことができたとしても、連打対策は必要かと思います。
あ、ひとつ目の案でもAPIを使ってマウスボタン状態を取得し、マウスボタンが離されるまでループということでも十分かもしれませんね。
ちょっと筆が滑って書きすぎました><
(こんなつもりでは・・・)
むしろボタンのようなコントロールを自分で作ってしまうとか.
WindowsAPIのDrawFrameControlでそれっぽくかけますし.
それならサブクラス化でもいいか
みなさま、本当に色々アドバイスありがとうございます。
すいません、出張ででてしまい、投稿が今日になってしまいました。
調べてみましたら、紅閃光さんのおっしゃる通り、Motor停止処理が終わった後にMotor駆動処理が行われている事がわかりました。
MouseDownとMouseUpの数の回数も一致していましたので、Motor駆動処理をStopFlagがTrueになるまでループするという方法でためしてみました。
見事、暴走は、なくなりました。
紅閃光さんはじめ、みなさま、本当にありがとうございました。
又、宜しくお願いします。
ツイート | ![]() |