读书人

PeekMessage取得消息时,为什么会失败?

发布时间: 2012-01-22 22:38:43 作者: rapoo

PeekMessage取得消息时,为什么会失败?SPY++却可以正常显示消息.
代码片段:

Private Const WM_USER = &H400
Private Const TRAY_CALLBACK = (WM_USER + 1001&)

...........

Public Function SetTray() '设置图标的过程
With TheData
.uID = 0
.hWnd = frmHwnd
.cbSize = Len(TheData)
.uFlags = NIF_ICON
.uCallbackMessage = TRAY_CALLBACK
.uFlags = .uFlags Or NIF_MESSAGE
End With
Shell_NotifyIcon NIM_ADD, TheData
End Function

Private Sub MessageLoop()
'在此循环内判断发送到目标句柄的消息
Dim mMessage As Msg
Dim I As Long

Do While Not bCancel
WaitMessage
I = PeekMessage(mMessage, frmHwnd, TRAY_CALLBACK, TRAY_CALLBACK, PM_REMOVE)
If I <> 0 Then
Debug.Print "Message: " & mMessage.Message
' Select Case Message.wParam
' Case WM_LBUTTONUP
' RaiseEvent MouseClick(vbLeftButton)
' Case WM_RBUTTONUP
' RaiseEvent MouseClick(vbRightButton)
' End Select
End If
DoEvents
Loop
End Sub

目的:

写一个类模块,不使用子类化,来完成托盘消息事件化返回.

使用一个标准模块可以完成这个功能,但是需要对某句柄子类化(SubClass),不想使用.

现在想封装到一个类里面去,让托盘事件能以事件方式返回,这样可以让程序的结构更好.

本来想用另一个线程来搞这个Do...Loop循环的,但那样的话,还是得带一个模块,并且在那个模块里面如何才能让类模块里的事件触发呢?

一个又一个问题....

但现在的关键是:

为什么这PeekMessage无法取得消息?

它总是返回0.

而我把回调消息换成WM_MOUSEMOVE后,鼠标在托盘区点击,移动等,都还是没办法取得消息.但是无论是自定义消息,还是WM_MOUSEMOVE,SPY++里都完全地拦截到了.证明消息是确实发过来了的.



可是在主窗体里面移动鼠标,却又可以正常地得到(这时PeekMessage就返回1了)

到底是哪一个环节出了问题?

消息发出后,先是由窗体的WndProc得到,还是先由PeekMessage得到?

谢谢!!

[解决办法]
setWindowsLong 或者 hook 之后,才可以吧。



————————————————————————————————————
写作,虽然每个人都会查阅辞海,可,不是人人都能写出不朽的篇章的。编程,如是也。

[解决办法]
看到另一个封装的代码是令
.uCallbackMessage = WM_MOUSEMOVE

然后传递一form中的picture控件给类

处理其OnMouseMove事件
[解决办法]
...这种循环好像很占用CPU的
[解决办法]
修改一下I = PeekMessage(mMessage, frmHwnd, TRAY_CALLBACK, TRAY_CALLBACK, PM_REMOVE)的参数,让它处理进程内的所有消息,然后在循环体内根据消息值和消息来源进行判断处理

[解决办法]
..........................................................

兄弟,偶来关注了,
虽然。。。看不太懂,
只能。。。蹭分了,呵呵:)

[解决办法]
我说的实现安全子类,并不是用汇编写的,而是直接的机器指令。但你不需懂汇编,更不需懂机器指令,你只要会用VB编一个窗体处理过程,并在其中加上EbMode判断与类方法调用即可。

写好这个过程,我前面提到的那个贴子中就能解决后面问题,它可自动将其转化为机器指令,并利用贴中另一个函数完成加载并使用。

具体说明,在贴中都有,我在那贴后半部分,发了修改后的全部代码,基本就是最终成形版了,它就是为VB专用的,你只需懂VB即可使用。
[解决办法]
PeekMessage 并不能截取到所有得消息

与GetMessage 不同,GetMessage 类似于子类化,所有消息必须通过她转发
而PeekMessage则自消息队列抽出,作出响应后并决定是否返回

如果用循环 + PeekMessage
则过程建立必须在 窗体show 出来之后,因为伴随 PeekMessage 使用得还有
WaitMessage ,Waitmessage 会检查消息,并处置消息所处得线程

此循环中最好使用 doevents ,此函数并非什么奇妙代码功能,而是一个简单的消息循环
具体作用及实现原理不煞述了

使用PeekMessage最好使用多线程承载此循环,否则比较好得解决方式是
sub form_load()
...
'自定义代码
...

show '必须先show出窗体
do until doevents = 0
waitmessage ...
if peekmessage(...) then ...
loop

end sub

这样一个过程

读书人网 >VB

热点推荐