问题描述:建立了一个win32窗口,上面存在一个自绘按钮控件,现在要对鼠标对于按钮的悬停事件进行监控。
有以下步骤:
1、在winproc中对msg进行选择,获取mouse move事件。从对应的lparam中获取当前鼠标的坐标点对。
2、用获取的坐标点对与控件区域信息进行比对,判断鼠标是否悬停在控件上。
第一步可以用另外一种方法实现:GetCursorPos(),用这个函数来获得当前光标的位置。这个函数的MSDN定义见最后备注。
当前面这些完成后来测试这个功能,发现鼠标定位会有偏差,如下图中黑框表示控件,红区表示在此区域内,光标才会被判定在控件上。
无论全屏还是窗口模式下都呈现这个问题。
解决过程:
1、对窗口进行全屏处理,用GetCursorPos(原本用的消息参数来获取的)输出对应鼠标位置信息。发现当不使用ClientToScreen函数时,鼠标定位信息与预期相应。而使用后会发现在左上角鼠标位置信息非零,为(-m,-n)此处m、n都为某个正整数,笔者机器上是(-8,-30)。
2、在上一步进行的同时,发现在边界上,即靠近屏幕四周的一个很小的环形区域内,消息方法无法获得鼠标位置信息。
3、综上,判定鼠标在2中区域时是否还在客户区。笔者在此时犯了个错误。获取客户区的矩形后并没有第一时间输出工作区矩形的信息,并且用的消息中的鼠标位置信息,而且只对左上角区域进行了判定,结果发现鼠标一直在客户区。事实上,获取的客户区区确实是左上角为(0,0),但是右下点并非在预设窗口大小应在位置。
4、输出客户区矩形信息后,发现右下角为(i,j),而且i+m与j+n正好和我们的窗口大小吻合。也就是说事实上,我们的客户区并没有在全屏时占据整个屏幕。
5、检查窗口样式,最终发现在CreateWindow时用WS_POPUP时,得到鼠标信息与预期一致。也即2中所知的区域为窗体border。
6、全屏模式下通过无边框的窗口样式即可解决定位问题,但是在窗口下该怎么处理这问题呢?
首先来看下,window style的参数枚举值:
Constant/value | Description |
---|---|
|
The window has a thin-line border. |
|
The window has a title bar (includes the WS_BORDER style). |
|
The window is a child window. A window with this style cannot have a menu bar. This style cannot be used with the WS_POPUP style. |
|
Same as the WS_CHILD style. |
|
Excludes the area occupied by child windows when drawing occurs within the parent window. This style is used when creating the parent window. |
|
Clips child windows relative to each other; that is, when a particular child window receives a WM_PAINT message, the WS_CLIPSIBLINGS style clips all other overlapping child windows out of the region of the child window to be updated. If WS_CLIPSIBLINGS is not specified and child windows overlap, it is possible, when drawing within the client area of a child window, to draw within the client area of a neighboring child window. |
|
The window is initially disabled. A disabled window cannot receive input from the user. To change this after a window has been created, use theEnableWindow function. |
|
The window has a border of a style typically used with dialog boxes. A window with this style cannot have a title bar. |
|
The window is the first control of |