フォーム外でマウスのクリックを判定するには?

解決


α  2001-04-09 00:57:36  No: 74120

今、マウスの動きを録画するプログラムを作っています。
ですが、フォーム外にマウスがでたときマウス座標は
取得することが出来ますが、クリックは判定できません。
どうすれば判定(取得)出来るのでしょうか。


PAPY  2001-04-10 21:39:12  No: 74121

えーと。
本来はデスクトップウインドウを「サブクラス化」するかフックプロシージャをインストールして「システム全体に影響を及ぼすフック」などで検知するのですがVBでは面倒なのでもっとも簡単な方法(タイマーイベントを利用)で検知します。

※「システム全体に影響を及ぼすフック」の方法はDelphiコーナーを見てください。

Private Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hWnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
Private Declare Function GetForegroundWindow Lib "user32" () As Long

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

Private Sub Timer1_Timer()  
  
  Dim nhWnd As Long
  Dim ClassName As String * 255

 'ユーザーが操作中のウインドウを取得
 nhWnd = GetForegroundWindow()
 '取得したウインドウのクラス名を取得
 Call GetClassName(nhWnd, ClassName, 255)
 'NULL文字除去
 If Left(ClassName, InStr(ClassName, Chr(0)) - 1) = "Progman" Then
     Label1 = "デスクトップがクリックされちゃいました。"
 Else
     Label1 = ""
 End If
    
End Sub

※Progmanはデスクトップのクラス名です。VC++などについている「Spy++」で確認すればわかります。


α  2001-04-13 02:26:40  No: 74122

報告遅れてすみません。
たしかにうごきましたが
デスクトップ以外で反応するのはあるのですか?

'ユーザーが操作中のウインドウを取得
nhWnd = GetForegroundWindow()
'取得したウインドウのクラス名を取得
Call GetClassName(nhWnd, ClassName, 255)

が、タネだと思いますが・・・


PAPY  2001-04-13 22:25:34  No: 74123

下記のようにすれば一応できますが、あまりよろしくない方法なので色々と変更して下さい。

Private Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hWnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
Private Declare Function GetForegroundWindow Lib "user32" () As Long

Dim MyClassname As String * 255
Private Sub Form_Load()
Timer1.Interval = 100
'自分のクラス名を取得しておく
Call GetClassName(hWnd, MyClassname, 255)
End Sub

Private Sub Timer1_Timer()
Dim nhWnd As Long
Dim ClassName As String * 255

'ユーザーが操作中のウインドウを取得
nhWnd = GetForegroundWindow()
'取得したウインドウのクラス名を取得
Call GetClassName(nhWnd, ClassName, 255)
'NULL文字除去&比較
If Left(ClassName, InStr(ClassName, Chr(0)) - 1) <> Left(ClassName, InStr(MyClassname, Chr(0)) - 1) Then
Label1 = "自分以外のウインドウが触られました。"
Else
Label1 = ""
End If

End Sub

※本格的に取得したい場合は下記のAPIを参照して下さい。但し、VBのデバッグは貧弱なので注意して下さい。

<Win32API>
'フック チェイン内にアプリケーション定義のフック プロシージャをインストールする
Public Declare Function SetWindowsHookEx Lib "user32" Alias "SetWindowsHookExA" (ByVal idHook As Long, ByVal lpfn As Long, ByVal hmod As Long, ByVal dwThreadId As Long) As Long
'フック チェイン内にインストールされたフック プロシージャを削除
Public Declare Function UnhookWindowsHookEx Lib "user32" (ByVal hHook As Long) As Long
'現在のフック チェインの次のフック プロシージャにフック情報を渡す
Public Declare Function CallNextHookEx Lib "user32" (ByVal hHook As Long, ByVal nCode As Long, ByVal Wparam As Long, Lparam As Long) As Long

<定数>
Public Const WM_LBUTTONDOWN = &H201  'マウス左ボタンクリック
Public Const WH_MOUSE = 7            'マウス メッセージを監視


α  2001-04-14 04:43:52  No: 74124

あまりよろしくない・・・とは?


PAPY  2001-04-14 23:44:26  No: 74125

とりあえず。下記のようなことがあるからです。・・・
・自分のクラス名と同じ場合がある(VB製のアプリはみんな同じクラス名?)
・左右どちらのマウスボタンが押されたかわからない
・Alt+Tabでウインドウを選択される場合もある(マウスクリックでない)
などなど・・・


α  2001-04-16 00:36:26  No: 74126

んー
どうやら難しいようですね。
どうも有り難う御座いました。


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








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