vb 怎么让鼠标移动到位于Image上Label控件时产生事件

ajunajun 2018-06-21 10:39:18
窗体上有一个Image,且Image铺满窗体,Image上有一个Label控件组
怎么让鼠标移动到Label控件上产生事件(比如移动到Label1(2)时,debug.print “进入Label1(2)”),离开Label时(即在Image上)无任何操作。
由于Image和Label两个控件都没有.hWnd属性,实在不知道怎么弄了。
...全文
571 12 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
舉杯邀明月 2018-06-24
  • 打赏
  • 举报
回复
引用 8 楼 bakw 的回复:
[quote=引用 7 楼 Chen8013 的回复:]
楼上的这个“方案”,不仅需要HOOK窗口消息,还要自己处理很多“事情”……
 比如,按鼠标指针坐标(要转换成“客户区坐标”才行)判断是否处于某控件上,
 当界面上相关控件有变动(大小、位置、数量等变动),就要增删相关代码、调整参数等。
 鼠标在窗体上的轻量级控件上移动时,窗体会接收到WM_MOUSEMOVE消息,
  如果窗体中的这些控件已经有MouseMove事件过程代码,可能会增加HOOK过程的逻辑复杂度。

 WM_MOUSELEAVE消息,若不“正确处理”,HOOK过程中不会收到这个消息。


还有,我有点怀疑楼主可能还不会HOOK窗口消息……

其实Timer控件+GetCursorPos就可以实现mouseout了
[/quote]
哈哈,其实我以前也是这么干的。
舉杯邀明月 2018-06-24
  • 打赏
  • 举报
回复
引用 9 楼 jiangsheng 的回复:
1 subclass不是hook,如果你不明白的话去查SetWindowHookEx和SetWindowLong的文档
2 WM_MOUSEMOVE是默认只发给鼠标光标下的窗口的,要想抓窗口之外的鼠标移动得去额外调用SetCapture。楼主没调用,那么只有在鼠标位于Label控件上才会往Label发的,根本不需要判断鼠标位置,Label收到这个消息就表明鼠标在Label之内了。窗体控件不管怎么变动,对Label在什么时候收到WM_MOUSEMOVE和WM_MOUSELEAVE是完全没有影响的。如果你不明白的话,去看WM_MOUSEMOVE和WM_MOUSELEAVE的文档。

我在VB6中,这方面的东西已经用得不少了,我岂会不明白!


你所谓的“子类化”,不能叫“HOOK”? 我还第1次听到这样的说法。
我觉得你这个概念,跟那种别人在说“标准DLL”特指用于动态加载并调用其导出函数的dll文件一样,
  本来这种“狭义”的说法,在一定的场合下,并没有什么歧义,也能为大多数人理解,
  而你非要去强调dll的定义,非要在别人讨论“某种”特定dll氛围中,去强调“ActiveX DLL也是标准DLL !”

SetWindowLong未必是HOOK,但 SetWindowLong(HWND, GWL_WNDPROC, ......)凭什么只能叫“子类化”而不能叫HOOK!


Lable、Image 这些都是“直接画”的,根本没有句柄,哪会有什么 WM_xxxx 的消息给你!
你可能很久没摸VB6了,这些已经忘记……

我看有些“不明白”的,恐怕是你自己。


蒋晟 2018-06-24
  • 打赏
  • 举报
回复
1 subclass不是hook,如果你不明白的话去查SetWindowHookEx和SetWindowLong的文档
2 WM_MOUSEMOVE是默认只发给鼠标光标下的窗口的,要想抓窗口之外的鼠标移动得去额外调用SetCapture。楼主没调用,那么只有在鼠标位于Label控件上才会往Label发的,根本不需要判断鼠标位置,Label收到这个消息就表明鼠标在Label之内了。窗体控件不管怎么变动,对Label在什么时候收到WM_MOUSEMOVE和WM_MOUSELEAVE是完全没有影响的。如果你不明白的话,去看WM_MOUSEMOVE和WM_MOUSELEAVE的文档。
脆皮大雪糕 2018-06-24
  • 打赏
  • 举报
回复
能简单实现的尽量简单实现,简单的搞不定了再考虑复杂的。关键看楼主能做到什么程度。
笨狗先飞 2018-06-23
  • 打赏
  • 举报
回复
引用 7 楼 Chen8013 的回复:
楼上的这个“方案”,不仅需要HOOK窗口消息,还要自己处理很多“事情”……
 比如,按鼠标指针坐标(要转换成“客户区坐标”才行)判断是否处于某控件上,
 当界面上相关控件有变动(大小、位置、数量等变动),就要增删相关代码、调整参数等。
 鼠标在窗体上的轻量级控件上移动时,窗体会接收到WM_MOUSEMOVE消息,
  如果窗体中的这些控件已经有MouseMove事件过程代码,可能会增加HOOK过程的逻辑复杂度。

 WM_MOUSELEAVE消息,若不“正确处理”,HOOK过程中不会收到这个消息。


还有,我有点怀疑楼主可能还不会HOOK窗口消息……

其实Timer控件+GetCursorPos就可以实现mouseout了
舉杯邀明月 2018-06-23
  • 打赏
  • 举报
回复
楼上的这个“方案”,不仅需要HOOK窗口消息,还要自己处理很多“事情”……
 比如,按鼠标指针坐标(要转换成“客户区坐标”才行)判断是否处于某控件上,
 当界面上相关控件有变动(大小、位置、数量等变动),就要增删相关代码、调整参数等。
 鼠标在窗体上的轻量级控件上移动时,窗体会接收到WM_MOUSEMOVE消息,
  如果窗体中的这些控件已经有MouseMove事件过程代码,可能会增加HOOK过程的逻辑复杂度。

 WM_MOUSELEAVE消息,若不“正确处理”,HOOK过程中不会收到这个消息。


还有,我有点怀疑楼主可能还不会HOOK窗口消息……
蒋晟 2018-06-22
  • 打赏
  • 举报
回复
不论鼠标是从窗口外移动到窗口内还是窗口内部移动都会有mousemove的。

你的需求是只在进入的时候写一次debug print,那么你需要抓WM_MOUSELEAVE ,在这里记录一个标志(鼠标离开了)。在mousemove的时候去检测这个标志,如果之前鼠标在窗口外面,那么说明这是鼠标进入了窗口的事件,debug print之后清除这个标志(鼠标已经在窗口里面了)。下次再有mousemove进来,如果查到上次鼠标位置还在窗口里面,所以是窗口内的移动,不做处理。

vb6没有封装WM_MOUSELEAVE,所以得子类化来在窗口过程里加入WM_MOUSELEAVE的处理。
具体参考https://www.codeproject.com/Articles/6844/Adding-MouseLeave-MouseHover-events-to-VB-Control

伪代码大概是这样:
初始化
标志=1
WM_MOUSEMOVE
debug.print
标志=0
WM_MOUSEMOVE
WM_MOUSEMOVE
.……
WM_MOUSELEAVE
标志=1
WM_MOUSEMOVE
debug.print
标志=0
WM_MOUSEMOVE
WM_MOUSEMOVE
.……
舉杯邀明月 2018-06-21
  • 打赏
  • 举报
回复
VB6的 Label、Image 等“轻量级控件”,都是没有 hWnd的。
但它们都支持 MouseMove( )事件。

不过:MouseMove事件只能检测到“已经移入”之后的事,无法监测到“离开”。
对于你目前的“情况”,Image是“铺满窗体”的,而Label控件往往比较小。
可以定义一个“窗体级变量”标识:
 当触发 Label控件的 MouseMove( )事件 时,表示鼠标已经移入Label的区域了,
     在其事件过程中“标识”移入,并做其它相关处理;
 当触发 Image控件的 MouseMove( )事件 时,表示鼠标已经移出 Label的区域了,
    在其事件过程中“清除标识”,并做其它相关处理。

不过,有比较大的局限性:
 如果从Label 控件中“迅猛”的移到临近的别的控件上(比如按钮、TextBox等),
虽然看起来“经过”了Image控件,但有可能也没触发Image控件的 MouseMove( )事件 ;
 如果Label紧挨着窗体边缘、鼠标从Label上从“挨着”的地方移出窗体;或者紧挨着别的控件、鼠标从“挨着控件”的
地方移到相应控件上……这时都无法执行“离开”的操作。
(当然“挨着控件”也可以在这个控件的 MouseMove( )事件 中处理;但“移出窗体”除了HOOK可能没法了)
 还可能有别的“麻烦”,就不一一细说了……

总之,还是考虑好真正的需求,是否真有必要要检测这个。
笨狗先飞 2018-06-21
  • 打赏
  • 举报
回复
有mousemove事件的,直接事件上写代码就好了,窗体不是自己程序里的吗?
of123 2018-06-21
  • 打赏
  • 举报
回复
我曾经用类似方法做过,鼠标移到显示某网址的 Label 上时,其 Caption 变为超链接形式(蓝色粗体下划线)。点击则打开对应网页。
of123 2018-06-21
  • 打赏
  • 举报
回复
Form 上 Image 布满,上面放了 Text1 以及 Label1 数组(0-2):
Private Sub Form_Load()
Label1(2).Caption = " No mouse found"
End Sub

Private Sub Image1_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
If Label1(2).Caption = "Mouse arrived" Then Label1(2).Caption = "Mouse left"
End Sub

Private Sub Label1_MouseMove(Index As Integer, Button As Integer, Shift As Integer, X As Single, Y As Single)
If Index = 2 Then
Label1(2).Caption = "Mouse arrived"
Else
If Label1(2).Caption = "Mouse arrived" Then Label1(2).Caption = "Mouse left"
End If
End Sub

Private Sub Text1_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
If Label1(2).Caption = "Mouse arrived" Then Label1(2).Caption = "Mouse left"
End Sub

脆皮大雪糕 2018-06-21
  • 打赏
  • 举报
回复
话不多说,给段代码


Option Explicit


Private Sub Form_Load()
'Image 铺满
Me.Image1.Top = 0
Me.Image1.Left = 0
Me.Image1.Width = Me.ScaleWidth
Me.Image1.Height = Me.ScaleHeight
End Sub

Private Sub Image1_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
Call SetMouseOnFlag(-1)
End Sub

Private Sub Label1_MouseMove(index As Integer, Button As Integer, Shift As Integer, X As Single, Y As Single)
Call SetMouseOnFlag(index)
End Sub
Private Sub SetMouseOnFlag(index As Integer)
Dim i As Integer
For i = Label1.LBound To Label1.UBound
If index = i Then
Label1(i).Tag = 1 '这个属性可以作为其他地方进行判断鼠标是否在上面的标志
Label1(i).FontBold = True
Label1(i).ForeColor = vbRed
Label1(i) = "鼠标在我这"

Else
Label1(i).Tag = -1
Label1(i).FontBold = False
Label1(i).ForeColor = vbBlack
Label1(i) = "找不着鼠标"
End If
Next
End Sub


1,453

社区成员

发帖
与我相关
我的任务
社区描述
VB 控件
社区管理员
  • 控件
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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