在窗口上跟踪显示鼠标位置-Win32版本
响应 WM_MOUSEMOVE 消息获得鼠标位置,再响应 WM_PAINT 将鼠标位置输出到窗口中,学习二者之间的关键步骤:调用 InvalidateRect() 以通知窗口重绘。


响应 WM_MOUSEMOVE 消息获得鼠标位置,再响应 WM_PAINT 将鼠标位置输出到窗口中,学习二者之间的关键步骤:调用 InvalidateRect() 以通知窗口重绘。
一、关键知识点
1. BeginPaint() 对比 GetDC()
两个API都能得到指定窗口的 DC (设备上下文),供程序后续在 DC 上画图、输出文字等。二者区别在于,BeginPaint() 是在窗口收到 WM_PAINT 消息后使用。窗口收到 WM_PAINT 意味着:这个窗口当前展现的内容已经失效,确实需要重画。而 GetDC() 是直接获得一个窗口的DC,然后直接开画。
再往前推一步:一个程序有机会响应某个窗口的消息(比如这里的 WM_PAINT),通常就意味着这个窗口是该程序自己创建出来的。
二者在参数上也有明显不同,BeginPaint() 除窗口句柄外,还需要先创建一个 PAINTSTRCT 的变量。
2. EndPaint()
GetDC() 调用后,要记得配套地写上 ReleaseDC(),类似,我们从 BeginPaint() 得到一个 DC,在完成使用该 DC 之后,要记得配套调用 EndPaint()。
3. WM_MOUSEMOVE 消息
坐标点在该消息的响应函数的 lParam 参数,该参数的类型的是 LPARAM, 它是Windows开发库定义的一个宏。其中 L 表示 “long” ,也就是长整型。然而,在 Windows 上,哪怕是 64 位的系统,long 其实仍然一个 int ,因此还是四字节。当它用作 WM_MOUSEMOVE 的参数时,从左到右,前两个字节(低字),存储鼠标移动后的 x 坐标,高字存储 y 坐标。
对一个整数(int,long)取低字,可使用宏 LOWORD(),其中 LO 是 “low / 低” 的缩写,对应的取高字使用 HIWORD(), “HI” 是 “High / 高” 的缩写。
4. InvalidateRect
函数原型(声明)为:
InvalidateRect 用于让指定窗口(hWnd)的指定区域(lpRect,说明见下)的绘图内容失效。
如果 lpRect 为空指针,则让整个窗口的(严格讲是客户区,即不包容标题栏、边框等)的绘图内容都失效。这样,窗口就会收到 WM_PAINT 消息,然后程序调用处理该消息的函数,开始重绘。
bErase 为真时,如果该窗口设置了合适的默认背景刷子(Brush,类似于 Pen,也是一种绘图资源 ), 系统将保证在重绘前,使用该刷子(特定颜色、样式),“刷掉” 原有内容。注意,窗口并不一定有合适的背景刷子。在我们的示例程序中,以下这一行保证了这一点:
其中的 RECT 是一个结构(struct),定义为:
即:通用 左、上、右、下 位置,定义一个矩形区域。
三、完整代码
三、效果示例
