座標を指定してマウスをクリックさせるには?

解決


yoshiri  2007-04-07 06:53:19  No: 98520

はじめまして  yoshiriです
今回  VB6で  指定した座標にマウスを移動させて  クリックさせるプログラムを勉強のためやっています
マウスの座標を求めるところまでは他のページを見て  GetCursorPosのAPIでやることにしました。
ですが  マウスを移動させ座標位置を変数などに代入するところとマウスを移動させてクリックさせるところを調べてもわかりませんでした

そこで
①Fキーなどのキーを押したことを認識させる
(これでマウスの座標を入れるコードを書く予定です。)
②マウス座標にマウスを移動させクリックさせる
以上2つをどうすればいいか教えていただきたいです
コードなども付けてくださると嬉しいです
よろしくお願いします


ドウ  2007-04-07 07:35:22  No: 98521

API関数の SetCursorPos と mouse_event を使うとできますよ〜。

以下はコマンドボタンCommand1にフォーカスがあるときに、F1キーを押したときに座標(100,100)にマウスを移動させてクリックするサンプルです。

---フォームモジュール---
Private Sub Command1_KeyDown(KeyCode As Integer, Shift As Integer)
    
    If KeyCode = vbKeyF1 Then
        SetCursorPos 100, 200

        mouse_event MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0
        mouse_event MOUSEEVENTF_LEFTUP, 0, 0, 0, 0
    End If
    
End Sub

---標準モジュール---
Public Declare Function SetCursorPos Lib "user32" (ByVal x As Long, ByVal y As Long) As Long
Public Declare Sub mouse_event Lib "user32" (ByVal dwFlags As Long, ByVal dx As Long, ByVal dy As Long, ByVal cButtons As Long, ByVal dwExtraInfo As Long)
Public Const MOUSEEVENTF_LEFTDOWN = &H2
Public Const MOUSEEVENTF_LEFTUP = &H4


yoshiri  2007-04-07 20:45:12  No: 98522

ドウさん  ありがとうございました
今  試してみています
マウスカーソルを移動する座標は  例で言うとF1キーを押したとき
変数などにマウスカーソルの座標を代入して  移動させるコードで呼び出してやればいいのでしょうか?
API初めて使うのでわからないもので...
よろしくお願いします


ドウ  2007-04-07 22:58:33  No: 98523

> マウスカーソルを移動する座標は  例で言うとF1キーを押したとき
> 変数などにマウスカーソルの座標を代入して  
> 移動させるコードで呼び出してやればいいのでしょうか?
はい。次のコードはF1,F2,F3を押したときそれぞれの場所に移動してクリックするサンプルです。

Private Sub Command1_KeyDown(KeyCode As Integer, Shift As Integer)

    Select Case KeyCode
        Case vbKeyF1
            Call マウスを移動してクリック(100, 200)
        Case vbKeyF2
            Call マウスを移動してクリック(50, 100)
        Case vbKeyF3
            Call マウスを移動してクリック(10, 30)
    End Select
End Sub
      
Private Sub マウスを移動してクリック(X As Long, Y As Long)
    SetCursorPos X, Y
    mouse_event MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0
    mouse_event MOUSEEVENTF_LEFTUP, 0, 0, 0, 0
End Sub

> API初めて使うのでわからないもので...
APIを使うときに私がよく見るサイトです。
「WinAPI Database for VB Programmer」
http://www.winapi-database.com/


yoshiri  2007-04-08 03:41:44  No: 98524

ドウさんたびたびありがとうございます
ちゃんと動きました  ありがとうございます
それで  座標を変数に代入するところで止まってしまっています
GetCursorPosとタイマーで座標を表示して  その情報をFキーを押したとき変数に代入したいのです  あとはその変数の情報をX,Yに代入してマウスを移動させたいと思っています
どうしてもエラーで完成しないのでアドバイスでもいいですから教えていただけないでしょうか?
よろしくお願いします


ドウ  2007-04-08 04:51:39  No: 98525

GetCursorPosで座標は得るところまでは行ったのですか?
もしそうなら、
GetCursorPos P
で得た座標はPOINTAPI型なので、代入は、
X = P.X
Y = P.Y
SetCursorPos X, Y
とするか、直接
SetCursorPos P.X, P.Y
とするかどちらでもいいです。

まだ座標が得られてないのなら、
Public Type POINTAPI
    X As Long
    Y As Long
End Type

Dim P As POINTAPI

GetCursorPos P
で得られます。

全体としては、こんなかんじかなあ〜
Dim P As POINTAPI
Dim X As Long
Dim Y As Long

Private Sub Form_Load()
    Timer1.Interval = 1000
End Sub

Private Sub Command1_KeyDown(KeyCode As Integer, Shift As Integer)
    
    If KeyCode = vbKeyF1 Then
        X = P.X
        Y = P.Y
        Text2.Text = Format(X, " ###") & "," & Format(Y, " ###")
    End If

End Sub

Private Sub Timer1_Timer()
    GetCursorPos P
    Text1.Text = Format(P.X, " ###") & "," & Format(P.Y, " ###")
    Beep
End Sub


yoshiri  2007-04-08 07:08:55  No: 98526

今までの文を参考に上の仕事を行うプログラムができました!
ドウさんありがとうございました
それで新たな問題ができまして

プログラムは完成して
さっそく今作っているプログラムに移植したら

なぜかキーを押しても変数に座標が代入されないようです

ちなみにプログラムでは何個かラベルとコマンドボタンを使用し
Now関数とタイマーで時刻を動的に表示しています

なぜでしょうか?
よろしくお願いします


ドウ  2007-04-08 07:58:48  No: 98527

> なぜかキーを押しても変数に座標が代入されないようです

上のサンプルは、フォームがアクティブでコマンドボタンにフォーカスがあるときにしか代入されません。
フォームが最小化されていたり、他のウインドウがアクティブだったりしたときは、他の方法でやらなければいけません。例えば、タイマーを使う方法が考えられます。

Public Declare Function GetKeyState Lib "user32" (ByVal nVirtKey As Long) As Integer

Dim キーを押している As Boolean
Dim P As POINTAPI
Dim X As Long
Dim Y As Long

Private Sub Form_Load()
    Timer2.Interval = 100
End Sub

Private Sub Timer2_Timer()
'F1キーを監視する。
    If GetKeyState(VK_F1) < 0 Then
        If キーを押している = False Then
            Beep
            Call 代入
            キーを押している = True
        End If
    Else
        If キーを押している = True Then
            キーを押している = False
        End If
    End If
End Sub

Private Sub 代入()
    GetCursorPos P
    X = P.X
    Y = P.Y
    Text2.Text = Format(X, " ###") & "," & Format(Y, " ###")
    Beep
End Sub

あと、質問するときはコードを示すといいですよ。どういうコードで、どこでエラーが出るのかを示せば回答してくれる人も多くなると思います。


yoshiri  2007-04-09 01:55:07  No: 98528

ドウさん  ありがとうございました  そうですか  ではいちおうできているコードは出しますね

値の代入を確かめるため  ラベルに一度代入しています
うまくいかないのでF5キーで動作するようにしています

'宣言の強制
Option Explicit

Dim Posi As POINTAPI
Dim Xp As Long
Dim Yp As Long

'マウス位置を指定
Private Declare Function SetCursorPos Lib "user32" (ByVal X As Long, ByVal Y As Long) As Long
    
'現在のマウスカーソルの位置座標を取得する(P387)
Private Declare Function GetCursorPos Lib "user32" (lpPoint As POINTAPI) As Long

'位置座標を受け取る構造体
Private Type POINTAPI
        X As Long
        Y As Long
End Type
   
----------------------------
Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)

'F3キーを押したかを確認
If KeyCode = vbKeyF3 Then
    Call GetCursorPos(Posi) 'マウス座標の取得
    lblSecretX.Caption = Posi.X     '隠れラベルに値を代入(X)
    lblSecretY.Caption = Posi.Y     '隠れラベルに値を代入(Y)
    
 X = lblSecretX.Caption
 Y = lblSecretY.Caption
End If

'F5キーで実行
If KeyCode = vbKeyF5 Then
    Call Setpo(X, Y)
End If

End Sub
-------------------------
Private Sub Setpo(X As Long, Y As Long)
    SetCursorPos X, Y
    mouse_event MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0
    mouse_event MOUSEEVENTF_LEFTUP, 0, 0, 0, 0
End Sub
----------------------------
Private Sub Timer1_Timer()
'ラベルに現在時間を表示
lblNowTime.Caption = Now

'現在のマウスポインタの座標を取得
          '現在のマウスポインタの位置座標
          

Call GetCursorPos(Posi)
    
lblPoint.Caption = "X=" & Posi.X & "  Y=" & Posi.Y

End Sub

'---標準モジュール---
Public Declare Function SetCursorPos Lib "user32" (ByVal X As Long, ByVal Y As Long) As Long
Public Declare Sub mouse_event Lib "user32" (ByVal dwFlags As Long, ByVal dx As Long, ByVal dy As Long, ByVal cButtons As Long, ByVal dwExtraInfo As Long)
Public Const MOUSEEVENTF_LEFTDOWN = &H2
Public Const MOUSEEVENTF_LEFTUP = &H4

いちおうこんな感じになっています  ほかはしっかりと記述されています

    lblSecretX.Caption = Posi.X     '隠れラベルに値を代入(X)
    lblSecretY.Caption = Posi.Y     '隠れラベルに値を代入(Y)

ここの文でF3キーが押されれば  ラベルに表示されるはずですがでません

なぜでしょうか?
よろしくお願いします


ドウ  2007-04-09 02:25:40  No: 98529

「コンパイル エラー:変数が定義されていません。」
というエラーが出るのでしょうか?

X = lblSecretX.Caption
Y = lblSecretY.Caption
の2行は、
Xp = lblSecretX.Caption
Yp = lblSecretY.Caption
の間違いと思います。

If KeyCode = vbKeyF5 Then
    Call Setpo(X, Y)
End If
も、
If KeyCode = vbKeyF5 Then
    Call Setpo(Xp, Yp)
End If
だと思います。

つまり、X, YとXp, Ypを間違えただけの話^^


yoshiri  2007-04-09 02:42:38  No: 98530

ドウさん  ありがとうございます
そこの変数は変更しました
ですが問題は

その変数に値が格納されず  ラベルにも表示されないのです
そのためマウスカーソルは  0,0  に移動するだけです

なぜでしょうか  よろしくお願いします


ドウ  2007-04-09 03:22:25  No: 98531

私が上のプログラムの実行した結果、うまく動きましたが、なぜでしょうね。

押すキーをファンクションキーでなく普通のキー(例えば、「a」とか、テンキーの「0」とか)にしてもそうなりますか?

If KeyCode = vbKeyF3 Then
の、
vbKeyF3 

vbKeyA

vbKeyNumpad0
などに変えてみる。

> ラベルにも表示されないのです
> そのためマウスカーソルは  0,0  に移動するだけです
ラベルに現在時間も表示されないのですか?
もしそうなら、タイマーはセットしてありますか?
Private Sub Form_Load()
    Timer1.Interval = 1000
End Sub

この行にブレークポイントを設定して、ちゃんと実行されているか確認してみてください。
Call GetCursorPos(Posi) 'マウス座標の取得


yoshiri  2007-04-09 03:55:38  No: 98532

ドウさん  ありがとうございます

コマンドボタンのKeyDownに  FormのKeyDownの文を貼り付けたら成功しました!

なぜこういうことがおきるのでしょうか?

またFormのKeyDownではだめなのでしょうか?

いろいろと質問攻めですいません

よろしくお願いします


ドウ  2007-04-09 04:10:06  No: 98533

なるほど、コマンドボタンがあったのですか。
Form1のKeyPreviewプロパティをTrueに設定してみて下さい。

Private Sub Form_Load()
    Form1.KeyPreview = True    
End Sub

KeyPreviewプロパティは、まずフォームがキー入力を受け取り、その後でフォーカスのあるコントロールがキー入力を受け取るようにしたいときに使います。


yoshiri  2007-04-09 04:42:40  No: 98534

ドウさん  いままで本当にありがとうございました
わからないことを丁寧に教えてくださって本当に助かりました
またわからないこともあると思いますがそのときはよろしくお願いします

追記:ちなみに前の記事で  コマンドボタンについて書いてあったんですが
見落とされたようです
こちらの伝達が悪くて申し訳ありませんでした


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加