win32窗口:关于鼠标定位位置偏移问题的原因及解决方法

本文介绍了在Win32窗口中遇到的鼠标定位偏差问题,详细阐述了解决全屏和窗口模式下鼠标位置不准确的步骤。问题源于ClientToScreen函数的使用,通过调整窗口样式,特别是使用WS_POPUP风格,或者参考DXUT范例中的处理方法,可以修正鼠标定位。解决方案包括调整窗口大小以匹配期望的客户区尺寸,确保鼠标位置信息与预期一致。
摘要由CSDN通过智能技术生成

问题描述:建立了一个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
WS_BORDER 0x00800000L

The window has a thin-line border.

WS_CAPTION 0x00C00000L

The window has a title bar (includes the WS_BORDER style).

WS_CHILD 0x40000000L

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.

WS_CHILDWINDOW 0x40000000L

Same as the WS_CHILD style.

WS_CLIPCHILDREN 0x02000000L

Excludes the area occupied by child windows when drawing occurs within the parent window. This style is used when creating the parent window.

WS_CLIPSIBLINGS 0x04000000L

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.

WS_DISABLED 0x08000000L

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.

WS_DLGFRAME 0x00400000L

The window has a border of a style typically used with dialog boxes. A window with this style cannot have a title bar.

WS_GROUP 0x00020000L

The window is the first control of

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值