我试图拦截使用WINAPI函数发送的Windows消息" BroadcastSystemMessage" (来自在创建新工作簿时发送此消息的XLL)。
我试图使用两种方法来做到这一点,但每种方法都有其缺点:
1)使用托管监听窗口:
但是,我不想冒用户关闭此监听窗口的风险,
listenForm.Show()
listenForm.visible = false
看起来很草率。
2)使用钩子:
然而,回拨" SetWindowsHookEx"只有几个参数:
Protected Function HookCallBack(code As Integer, wParam As IntPtr, lParam As IntPtr) As Integer
我正在寻找一种方法来访问" msg" struct,其中包含我注册的信息" RegisterWindowMessage"。
在这里," lParam"指向这个结构,我可以使用:
Dim output(100) As Byte
Marshal.Copy(e.lParam, output, 0, 100)
取消引用此指针。我不知道如何解析结果,也让我感到困扰的是我离管理的宇宙很远。
我的问题:每种方式都可以修复,拦截消息或做类似事情的标准方法是什么?
答案 0 :(得分:1)
Show()方法调用只是获取本机窗口的方法之一。您也可以在构造函数中自己创建它:
Public Sub new
InitializeComponent()
Me.CreateHandle()
End Sub
或者,如果您无法避免Show()调用,因为它是您应用的启动形式,请执行以下操作:
Protected Overrides Sub SetVisibleCore(value As Boolean)
If Not Me.IsHandleCreated then
value = False
Me.CreateHandle()
End If
MyBase.SetVisibleCore(value)
End Sub
请注意,在任何情况下都不会触发Load事件,因此将您拥有的任何代码移动到表单类的构造函数中。
不要使用窗口挂钩,您所要做的就是覆盖WndProc()子例程以查看广播消息:
Protected Overrides Sub WndProc(ByRef m As Message)
If m.Msg = theRegisteredMessage Then
'' etc...
End If
MyBase.WndProc(m)
End Sub
通过BroadcastSystemMessage()支持使用HWND_BROADCAST的普通SendMessage()。或者更好的是,Socket让你不必大声喊叫。