首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > VB >

PeekMessage取得消息时,为什么会失败?SPY++却可以正常显示消息.解决方案

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

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

这样一个过程

热点排行