- フィルター関数
CallNextHookEx
での呼び出しをスキップすることは、一般的に悪い考えです。GetMsgProc
これを行うと、チェーン内の他のフィルター関数は呼び出されません。おそらく、開発マシンには何もありませんが、「実際には」フックをインストールした他のアプリケーションが存在するでしょう。これらのアプリケーションは、フィルター関数が呼び出されないようにすると、誤動作します。
- キューから単に覗かれただけで削除されていないメッセージを分析したくないでしょう。キューから削除されたメッセージに対して
GetMsgProc
呼び出されます。wParam = PM_REMOVE
VB6 や C++ など、API の MSDN 仕様を無視するのは危険な行為です。これは、GetMsgProc
フィルター関数がその最初の引数の値に基づいて決定を行う方法です。
コード[中]
フック プロシージャがメッセージを処理する必要があるかどうかを指定します。code が HC_ACTION の場合、フック プロシージャはメッセージを処理する必要があります。コードが 0 未満の場合、フック プロシージャはメッセージをそれ以上処理せずに CallNextHookEx 関数に渡し、CallNextHookEx によって返された値を返す必要があります。
http://msdn.microsoft.com/en-us/library/windows/desktop/ms644981%28v=vs.85%29.aspx
動作するはずですがCopyMemory
(正しく宣言すると仮定して)、ここでは気にしません。フィルター関数の 3 番目のパラメーターを として宣言しても問題ありませんByRef lParam As MSG
。
以下は、標準モジュールに配置する必要があるコードです (フックをインストールする他のコードと同様)。たとえば、メインフォームに配置されたコントロールWM_RBUTTONDOWN
へのメッセージを盗聴するために使用すると、うまくいきます。TextBox
Option Explicit
'http://msdn.microsoft.com/en-us/library/windows/desktop/dd162805%28v=vs.85%29.aspx
Private Type tagPOINT
x As Long
y As Long
End Type
'http://msdn.microsoft.com/en-us/library/windows/desktop/ms644958%28v=vs.85%29.aspx
Private Type MSG
hWnd As Long
message As Long
wParam As Long
lParam As Long
time As Long
pt As tagPOINT
End Type
Private bHooked As Boolean
Private hHook As Long
Private hHwndToSniff As Long
Private Const HC_Action As Long = &H0
Private Const PM_NOREMOVE As Long = &H0
Private Const PM_REMOVE As Long = &H1
Private Const WH_GETMESSAGE As Long = &H3
Private Const WM_RBUTTONDOWN As Long = &H204
'http://msdn.microsoft.com/en-us/library/windows/desktop/ms644974%28v=vs.85%29.aspx
Private Declare Function CallNextHookEx Lib "user32" _
(ByVal hHook As Long, ByVal ncode As Long, ByVal wParam As Long, lParam As Any) As Long
'http://msdn.microsoft.com/en-us/library/windows/desktop/ms644990%28v=vs.85%29.aspx
Private 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
'http://msdn.microsoft.com/en-us/library/windows/desktop/ms644993%28v=vs.85%29.aspx
Private Declare Function UnhookWindowsHookEx Lib "user32" _
(ByVal hHook As Long) As Long
Public Sub RemoveHook()
If bHooked Then
UnhookWindowsHookEx hHook
bHooked = False
End If
End Sub
Public Sub SetHook(ByVal hThreadToHook As Long, hHwndFilter As Long)
If Not bHooked Then
hHook = SetWindowsHookEx(WH_GETMESSAGE, AddressOf GetMsgProc, 0, hThreadToHook)
If hHook > 0 Then
bHooked = True
hHwndToSniff = hHwndFilter
Else
Debug.Assert False
End If
End If
End Sub
'http://msdn.microsoft.com/en-us/library/windows/desktop/ms644981%28v=vs.85%29.aspx
Private Function GetMsgProc(ByVal uCode As Long _
, ByVal wParam As Long _
, ByRef lParam As MSG) As Long
If uCode = 0 Then
If wParam = PM_REMOVE Then
If lParam.message = WM_RBUTTONDOWN Then
If lParam.hWnd = hHwndToSniff Then
MsgBox "You right-clicked a text box!"
End If
End If
End If
End If
GetMsgProc = CallNextHookEx(hHook, uCode, wParam, lParam)
End Function
フックは、次の方法でフォーム モジュールにインストールされます。
SetHook App.ThreadID, Me.Text1.hWnd