如何在VB例程中接收自定义消息
您可以用API函数SetWindowLong指定处理消息的窗口过程(window procedure)为自定义的函数WindowProc,捕获消息ID为WM_USER
+
1的自定义消息或系统消息。并且,为了保证窗口能正确的响应消息,需要保存原来默认的窗口过程并在自定义函数WindowProc中调用。如下例,在按钮事件中发送自定义消息,WindowProc捕获了窗口大小变化的系统定义消息和用户自定义的消息并显示用户自定义的消息参数wParam:
在Moduel中加入以下代码,
Option
Explicit
Private
Const
GWL_WNDPROC
=
-
4
Public
Const
GWL_USERDATA
=
(
-
21
)
Public
Const
WM_SIZE
=
&
H5
Public
Const
WM_USER
=
&
H400
Private
Declare
Function
CallWindowProc
Lib
"
user32
"
Alias
_
"
CallWindowProcA
"
(
ByVal
lpPrevWndFunc
As
Long
, _
ByVal
hwnd
As
Long
,
ByVal
Msg
As
Long
, _
ByVal
wParam
As
Long
,
ByVal
lParam
As
Long
)
As
Long
Public
Declare
Function
GetWindowLong
Lib
"
user32
"
Alias
"
GetWindowLongA
"
_
(
ByVal
hwnd
As
Long
,
ByVal
nIndex
As
Long
)
As
Long
Private
Declare
Function
SetWindowLong
Lib
"
user32
"
Alias
_
"
SetWindowLongA
"
(
ByVal
hwnd
As
Long
, _
ByVal
nIndex
As
Long
,
ByVal
dwNewLong
As
Long
)
As
Long
Public
Declare
Function
SendMessage
Lib
"
user32
"
Alias
"
SendMessageA
"
(
ByVal
hwnd
As
Long
,
ByVal
wMsg
As
Long
,
ByVal
wParam
As
Long
, lParam
As
Any)
As
Long
Public
Function
Hook(
ByVal
hwnd
As
Long
)
As
Long
Dim
pOld
As
Long
‘指定自定义的窗口过程
pOld
=
SetWindowLong(hwnd, GWL_WNDPROC, _
AddressOf
WindowProc)
‘保存原来默认的窗口过程指针
SetWindowLong hwnd, GWL_USERDATA, pOld
Hook
=
pOld
End Function
Public
Sub
Unhook(
ByVal
hwnd
As
Long
,
ByVal
lpWndProc
As
Long
)
Dim
temp
As
Long
注释:Cease subclassing.
temp
=
SetWindowLong(hwnd, GWL_WNDPROC, lpWndProc)
End Sub
Function
WindowProc(
ByVal
hw
As
Long
,
ByVal
uMsg
As
Long
, _
ByVal
wParam
As
Long
,
ByVal
lParam
As
Long
)
As
Long
If
uMsg
=
WM_SIZE
Then
‘处理WM_SIZE消息
MsgBox
"
SIZE
"
End
If
If
uMsg
=
WM_USER
+
1
Then
MsgBox
wParam
End
If
Dim
lpPrevWndProc
As
Long
‘查询原来默认的窗口过程指针
lpPrevWndProc
=
GetWindowLong(hw, GWL_USERDATA)
‘调用原来的窗口过程
WindowProc
=
CallWindowProc(lpPrevWndProc, hw, uMsg,wParam, lParam)
End Function
在Form中加入以下代码:
Dim
wParam
As
Long
Dim
lParam
As
Long
Dim
lResult
As
Long
Private
Sub
Command1_Click()
wParam
=
12345
lResult
=
SendMessage(
Me
.hwnd, WM_USER
+
1
, wParam, lParam)
End Sub
Private
Sub
Form_Load()
Me
.Tag
=
Hook(
Me
.hwnd)
End Sub
Private
Sub
Form_Unload(Cancel
As
Integer
)
Unhook
Me
.hwnd,
Me
.Tag
End Sub
在VB中用自定义过程捕获并处理消息的详细信息和例子请参考:
Q170570 HOWTO: Build a Windows Message Handler
with
AddressOf
in
Visual
http:
//
support.microsoft.com
/
support
/
kb
/
articles
/
q170
/
5
/
70
.asp
Q168795 HOWTO: Hook Into a Window注释:s Messages
Using
AddressOf
http:
//
support.microsoft.com
/
support
/
kb
/
articles
/
q168
/
7
/
95
.asp