如何知道鼠标是否在win32中进入和离开任何控件? [英] How to know if mouse entered and leave in any control in win32 ?

查看:241
本文介绍了如何知道鼠标是否在win32中进入和离开任何控件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好,

我正在使用win 32 api编写GUI库。我的语言是Nim,但这不是问题。

为了模仿vb.net风格,我在这个库中设计了一个事件驱动的方法。我的lib中的每个控件类都有一些名为events的公共成员。而且他们都是UINT。喜欢 -

ButtonClass.click = BN_CLICKED

FormClass.click = WM_LBUTTONDOWN

每个类都有一个AddHandler函数。这是签名。

AddHandler(evt,pFn)

-evt = events

-pFn =函数指针

因此,此AddHandler将在列表中添加所有用户函数和相应的消息。然后,在WndProc函数中,我可以遍历此列表并调用适当的函数。到目前为止,一切似乎都还可以。

但我希望我的控制类能够处理鼠标输入,悬停和离开事件。这造成了一个问题。我在win api中找不到一般控制鼠标输入消息。我知道按钮使用BCN_HOTITEMCHANGE,它对我有用。但我找不到适用于每个控件的解决方案。如何解决这个问题。

我刚用TrackMouseEvent测试过。这是我的测试场景 -

1.当鼠标指针悬停在任何控件上时,我收到一条WM_MOUSELEAVE消息。当指针返回客户区时,我收到一条WM_MOUSEMOVE消息。

2.所以我开始在WM_MOUSELEAVE中跟踪鼠标并停止在WM_MOUSEMOVE中跟踪。我的目的是将鼠标悬停消息放在每个控件的顶部。但这并不像打算那样有效。任何帮助?

一些额外的信息 -

1.对于所有控制类,我创建了一个CTL_MOUSE_ENTER,CTL_MOUSE_HOVER,CTL_MOUSE_LEAVE消息。

然后我为这些事件添加了函数指针并将其保存在列表中。

3.在WndProc中,我想遍历此列表并调用该函数。

4.要查找哪个控件在鼠标指针下,我使用GetMousePos& ScreenToClient函数。

5.然后我尝试使用WindowFromPoint函数但没有工作。

6.然后我试图用控件的RECT找到控件,但没有'工作了。

现在,我的所有实验都失败了。



我尝试过的事情:



 proc TrackMouse *(句柄:HWND)= 
var lpTME:TTRACKMOUSEEVENT
lpTME.cbSize = cast [DWORD](sizeof (TTRACKMOUSEEVENT))
lpTME.dwFlags = TME_HOVER或TME_LEAVE
lpTME.dwHoverTime = 100 #HOVER_DEFAULT
lpTME.hwndTrack = handle
discard COMCTL32_TrackMouseEvent(lpTME)

解决方案

您应该使用在鼠标移出控件之前引发的WM_KILLFOCUS事件。



请参阅: WM_KILLFOCUS消息 - Windows应用程序| Microsoft Docs [ ^

Hi all,
I am writting a GUI library using win 32 api. My laguage is Nim, but that is not a matter here.
For mimicking vb.net style, i have designed an event driven method in this library. Every control class in my lib has some public members called events. And all of them are UINTs. like --
ButtonClass.click = BN_CLICKED
FormClass.click = WM_LBUTTONDOWN
Each class has an AddHandler function. This is the signature.
AddHandler(evt, pFn)
-evt = events
-pFn = function pointer
So this AddHandler will add all user functions and appropriate messages in a list. Then, in the WndProc function, i can loop through this list and call appropriate function. Everything seems to be ok so far.
But I want my control classes to handle mouse enter, hover and leave events too. This created a problem. I can't find a general control mouse enter message in win api. I know that button's use BCN_HOTITEMCHANGE and it worked for me. But i can't find a solution which is applicable for every controls. How to fix this problem.
I just tested with TrackMouseEvent. This was my testing scenario-
1. When mouse pointer hovered over any control, i get a WM_MOUSELEAVE message. And when pointer comes back to client area, i get a WM_MOUSEMOVE message.
2. So i started tracking mouse in WM_MOUSELEAVE and stopped tracking in WM_MOUSEMOVE. My intention was to get the mouse hover message on the top of every controls. But this was not worked as in intend. Any help ?
Some extra info--
1. For all control class, i have created a CTL_MOUSE_ENTER, CTL_MOUSE_HOVER, CTL_MOUSE_LEAVE messages.
2. Then i added function pointers for these events and keep it in a list.
3. In WndProc, i want to loop through this list and call the function.
4. To find which control is under mouse pointer, i use GetMousePos & ScreenToClient functions.
5. And then i tried with WindowFromPoint function but didn't worked.
6. Then i tried to find the control with the RECT of the control, but didn't worked.
Now, all my experiments were failed.

What I have tried:

proc TrackMouse*(handle : HWND) = 
    var lpTME : TTRACKMOUSEEVENT
    lpTME.cbSize = cast[DWORD](sizeof(TTRACKMOUSEEVENT))
    lpTME.dwFlags = TME_HOVER or TME_LEAVE 
    lpTME.dwHoverTime = 100 #HOVER_DEFAULT
    lpTME.hwndTrack = handle
    discard COMCTL32_TrackMouseEvent(lpTME)

解决方案

You should use the WM_KILLFOCUS event which is raised just before the mouse moves out of a control.

See: WM_KILLFOCUS message - Windows applications | Microsoft Docs[^]


这篇关于如何知道鼠标是否在win32中进入和离开任何控件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆