任务栏图标与mousemove事件的问题!

zgklem 2010-02-15 07:35:49

谁能解释一下,蓝色部分的意思,X为什么会与WM_LBUTTONUP或WM_RBUTTONUP的值相等!一个坐标值,一个是消息的参数值!为什么可以这样用?


Option Explicit
Const max_tooltip As Integer = 64
Const nif_icon = &H2 '删除图标
Const NIF_MESSAGE = &H1 'NIF_MESSAGE指定uCallbackMessage有效
Const NIF_TIP = &H4 'NIF_TIP指定szTip有效
Const NIM_ADD = &H0 '添加图标到任务栏提示区
Const NIM_DELETE = &H2
Const WM_MOUSEMOVE = &H200
Const WM_LBUTTONDOWN = &H201
Const WM_LBUTTONUP = &H202
Const WM_LBUTTONDBLCLK = &H203
Const WM_RBUTTONDOWN = &H204
Const WM_RBUTTONUP = &H205
Const WM_RBUTTONDBLCLK = &H206
Const SW_RESTORE = 9
Const SW_HIDE = 0
Private Type NOTIFYICONDATA
cbSize As Long 'cbSize是NOTIFYICONDATA结构的大小
hwnd As Long 'hWnd是当前窗口的句柄
uID As Long 'uID指定图标的标识符
uFlags As Long 'uFlags是一组参数
uCallbackmessage As Long 'uCallbackMessage是一个自定义消息,当鼠标在图标所属的正方形区域内有消息发生,比如单击了图标时,系统就会发送一个消息到uCallbackMessage中
hIcon As Long 'hIcon是图标的句柄
szTip As String * max_tooltip 'szTip指定的文字信息会在你将鼠标移到图标上时以浮动方式显示出来
End Type
Private Declare Function ShowWindow Lib "user32" (ByVal hwnd As Long, _
ByVal nCmdShow As Long) As Long

Private Declare Function Shell_NotifyIcon Lib "shell32.dll" Alias "Shell_NotifyIconA" _
(ByVal dwMessage As Long, lpData As NOTIFYICONDATA) As Long
'dwMessage指定你要加入?删除?还是修改图标 分别为NIM_ADD?NIM_DELETE和NIM_MODIFY
'lpData指向NOTIFYICONDATA类型变量的指针

Private nfIconData As NOTIFYICONDATA

Private Sub Form_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
Dim lMsg As Single
lMsg = X / Screen.TwipsPerPixelX
If lMsg = WM_RBUTTONUP Or lMsg = WM_LBUTTONUP Then Me.PopupMenu sys
End Sub


Private Sub Command1_Click()
nfIconData.hwnd = Me.hwnd
nfIconData.uID = Me.Icon
nfIconData.uFlags = nif_icon Or NIF_MESSAGE Or NIF_TIP
nfIconData.uCallbackmessage = WM_MOUSEMOVE
nfIconData.hIcon = Me.Icon.Handle
nfIconData.szTip = "System Tray Example" & vbNullChar
nfIconData.cbSize = Len(nfIconData)
Shell_NotifyIcon NIM_ADD, nfIconData
End Sub

Private Sub command2_Click()
Call Shell_NotifyIcon(NIM_DELETE, nfIconData)
End Sub

Private Sub command3_Click()
ShowWindow Me.hwnd, SW_HIDE
End Sub

Private Sub command4_Click()
Unload Me
End Sub

Private Sub Command5_Click()
Me.Visible = False
End Sub

Private Sub move_Click()
Call Shell_NotifyIcon(NIM_DELETE, nfIconData)
End Sub

Private Sub show_Click()
Me.Visible = True
End Sub

Private Sub exit_Click()
Unload Me
End Sub



...全文
326 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
钦犯 2011-11-30
  • 打赏
  • 举报
回复
加个前提If Y=0 勉强可以回避冲突
钦犯 2011-11-30
  • 打赏
  • 举报
回复
我也理解了,不过确实微软在偷懒,这个代码并不完美!

在主窗体正常化情况下,如果MouseMove到坐标X=517(&H205)*Screen.TwipsPerPixelX时,也会触发托盘右击程序。
BD6500K 2010-09-29
  • 打赏
  • 举报
回复
已经完全理解了,微软太聪明了。这个代码完美。傻冒的是那些,不懂装懂的人。

当鼠标在托盘发生消息的时候,请问窗口还会有MOUSEMOVE的行为吗?各位同学们?
不可能会有啊,对不对。所以窗口代劳,免去了召唤WindowProc等这些无意义的行为。

为什么说无意义,因为窗体Form的消息,实际上和WindowProc是一回事。Windows是微软写的,他比谁都清楚系统是怎么运作的。用窗口来做也是一回事,何必多次一举。有些傻冒想当然的说,会影响窗体的消息,狗屁。请问你怎么让托盘图标和窗体位置重合?进而影响窗体的MOUSEMOVE消息?俗话说的好,满大街的轮子卖,你还要准备自己造个轮子吗?Windows已经写好了,API是非得要用的时候,才用。除非你喜欢另外写一个Windows,那就好好的,什么都用API去吧。
zgklem 2010-09-28
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 topbofndc 的回复:]
没看懂呀。
[/Quote]
何处不懂?
zgklem 2010-09-28
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 bd6500k 的回复:]
引用 8 楼 yachong 的回复:
关键在于这一句:
nfIconData.uCallbackmessage = WM_MOUSEMOVE
一般情况下,这里不用 WM_MOUSEMOVE,而是自定义一个新的消息类型,比如9999,或者WM_USER + 100之类的。
然后自己写一个WindowsProc函数拦截这个消息,根据lPara的值判断是左击还是右击了图标。

楼主这个写法……
[/Quote]
这其实是状态栏传递消息的一个机制!是微软定的!楼上的猜测应该是正确的!
BD6500K 2010-09-27
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 bcrun 的回复:]
这也算可用,那你对可用的要求也太低了.竟然拿X坐标来推算消息编号!同学啊,夸张点说,不能只要不导致VB异常中止的代码就算是可用的吧.
[/Quote]

别在这里乱扯了,还好我看这帖子不是2002年是,确定是2010 2月。
最烦你这种人,微软有桥,你不走,非得自己游泳过去,显示自己的游泳本领。

这也就算了,还诈唬桥上的,说,当心桥断喔,断了,你要掉水里。殊不知,桥断了,砸的是你,而且你已经在水里了。

请你证明这段代码,怎么就会异常中止,所有人用的都没问题!而且我还要把答案揭底了,很不幸,这段代码就是MSDN上推荐使用的!
http://support.microsoft.com/kb/176085
topbofndc 2010-09-27
  • 打赏
  • 举报
回复
没看懂呀。
BD6500K 2010-09-27
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 yachong 的回复:]
关键在于这一句:
nfIconData.uCallbackmessage = WM_MOUSEMOVE
一般情况下,这里不用 WM_MOUSEMOVE,而是自定义一个新的消息类型,比如9999,或者WM_USER + 100之类的。
然后自己写一个WindowsProc函数拦截这个消息,根据lPara的值判断是左击还是右击了图标。

楼主这个写法取巧了,他省去了自己写WindowsPro……
[/Quote]

谢谢,茅塞顿开。基本理解了,网上的尽是瞎扯蛋。
像百度里面的,就太能装B了,傻到不行。几乎相同的代码,很不幸,就是微软提供的。在MSDN上。
zgklem 2010-02-27
  • 打赏
  • 举报
回复
引用 8 楼 yachong 的回复:
关键在于这一句:
nfIconData.uCallbackmessage = WM_MOUSEMOVE
一般情况下,这里不用 WM_MOUSEMOVE,而是自定义一个新的消息类型,比如9999,或者WM_USER + 100之类的。
然后自己写一个WindowsProc函数拦截这个消息,根据lPara的值判断是左击还是右击了图标。

楼主这个写法取巧了,他省去了自己写WindowsProc函数,而是在单机图标时扔给窗体一个WM_MOUSEMOVE消息,由窗体默认的WindowsProc过程拦截处理这个消息。
窗体接收到 WM_MOUSEMOVE消息后,会触发Form_mousemove事件。这时候估计是把lPara参数转换成了mousemove事件的X参数。API传递的都是像素值,而VB默认使用缇,所以应该是X=lPara*Screen.TwipsPerPixelX。
所以,在Form_mousemove事件中,X/Screen.TwipsPerPixelX就还原成了原来的lPara参数,即WM_LBUTTONUP或WM_RBUTTONUP

猜的,大约是这样吧。

目前还是不懂!以后再理解吧!结贴!
yachong 2010-02-17
  • 打赏
  • 举报
回复
关键在于这一句:
nfIconData.uCallbackmessage = WM_MOUSEMOVE
一般情况下,这里不用 WM_MOUSEMOVE,而是自定义一个新的消息类型,比如9999,或者WM_USER + 100之类的。
然后自己写一个WindowsProc函数拦截这个消息,根据lPara的值判断是左击还是右击了图标。

楼主这个写法取巧了,他省去了自己写WindowsProc函数,而是在单机图标时扔给窗体一个WM_MOUSEMOVE消息,由窗体默认的WindowsProc过程拦截处理这个消息。
窗体接收到 WM_MOUSEMOVE消息后,会触发Form_mousemove事件。这时候估计是把lPara参数转换成了mousemove事件的X参数。API传递的都是像素值,而VB默认使用缇,所以应该是X=lPara*Screen.TwipsPerPixelX。
所以,在Form_mousemove事件中,X/Screen.TwipsPerPixelX就还原成了原来的lPara参数,即WM_LBUTTONUP或WM_RBUTTONUP

猜的,大约是这样吧。
bcrun 2010-02-16
  • 打赏
  • 举报
回复
这也算可用,那你对可用的要求也太低了.竟然拿X坐标来推算消息编号!同学啊,夸张点说,不能只要不导致VB异常中止的代码就算是可用的吧.
zgklem 2010-02-16
  • 打赏
  • 举报
回复
引用 1 楼 bcrun 的回复:
你这代码的来源有问题,这三句完全不对嘛
Dim lMsg As Single
lMsg = X / Screen.TwipsPerPixelX
If lMsg = WM_RBUTTONUP Or lMsg = WM_LBUTTONUP
另外,上面代码中,那个If判断的意思,一般是说这个消息编号是WM_RBUTTONUP或WM_LBUTTONUP都可以(表达式值为true),并不是说"WM_LBUTTONUP或WM_RBUTTONUP的值相等"

这个代码是可以用的!蓝色部分完成的功能是当鼠标左键或右键点击任务栏里的图标时就弹出菜单!

我不能明白的是为什么可以这样使用X!
lb_bn 2010-02-16
  • 打赏
  • 举报
回复
帮顶一下。。。。。。。
zgklem 2010-02-16
  • 打赏
  • 举报
回复
引用 3 楼 bcrun 的回复:
这也算可用,那你对可用的要求也太低了.竟然拿X坐标来推算消息编号!同学啊,夸张点说,不能只要不导致VB异常中止的代码就算是可用的吧.

其实我只想知道原理!为什么会出现这个结果!
zgklem 2010-02-16
  • 打赏
  • 举报
回复
引用 4 楼 chinaboyzyq 的回复:
http://zhidao.baidu.com/question/99675057.html

它里面也没有说清楚,这个我看过!
bcrun 2010-02-15
  • 打赏
  • 举报
回复
你这代码的来源有问题,这三句完全不对嘛
Dim lMsg As Single
lMsg = X / Screen.TwipsPerPixelX
If lMsg = WM_RBUTTONUP Or lMsg = WM_LBUTTONUP
另外,上面代码中,那个If判断的意思,一般是说这个消息编号是WM_RBUTTONUP或WM_LBUTTONUP都可以(表达式值为true),并不是说"WM_LBUTTONUP或WM_RBUTTONUP的值相等"

2,464

社区成员

发帖
与我相关
我的任务
社区描述
VBA(Visual Basic for Applications)是Visual Basic的一种宏语言,是在其桌面应用程序中执行通用的自动化(OLE)任务的编程语言。
社区管理员
  • VBA
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧