Window桌面应用程序初学(2)--键盘互动与窗体更新

实习第二天,对windows桌面应用中的互动有了更多理解。可以断定,一切与窗口内容、影响内容呈现的互动都会调用WM_PAINT进行重绘。
与上一讲一样,就布置的一项课堂作业我记录一下本节课的主要所学:

1. 任务描述:

就键盘上下左右按键能在窗体中触发提示信息,表示按键是按下还是未按状态。

2. 实现思路:

因为上课迟到了一小会没有被告知用while函数里面相关的映射接口实现,所以更具昨天学到的知识我思考出自己的做法——我也认为比起后来老师演示的方法更底层:首先定义四个int的全局变量

int IsUpDOWN = 0, IsDownDOWN = 0, IsLeftDOWN = 0, IsRightDOWN = 0;

用来记录四个方向键是否被按下,在WndProc()函数里面,对WM_KEYDOWN和WM_KEYUP自定义来修改上面四个变量的值,然后在WndProc()里面对WM_PAINT进行自定义,更具四变量状态绘制不同的内容。

3. 实现过程与遇到的问题的解决:

·首先对四个全局变量的值处理很简单
在这里插入图片描述
在WndProc()里面处理WM_KEYDOWN和WM_KEYUP,更具wParam不同修改全局变量的0、1状态;

·接下来的问题是如何写WM_PAINT呢。我通过查找CSDN一个画出对联的小实例(https://blog.csdn.net/sinat_32582203/article/details/73251025)
学习了画刷画笔,模仿着画出了四个红色正方形:
在这里插入图片描述在这里插入图片描述

·但是当我使用四个方向键全局变量来控制矩形的绘制时却发现了问题:
在这里插入图片描述在这里插入图片描述
在窗口中,无论按什么都无法显示方块。我意识到是没有进行更新,但是我没有急着去改代码,我知道拖动窗口时会调用更新的语句,所以我尝试按住一个方向键,然后拖动窗口试图让系统调用更新语句,但是很可惜失败了。

·我尝试在每次更新完方向键全局变量后立刻手动调用WndProc的WM_PAINT:在这里插入图片描述
然而没有效果,通过debug模式我确认进入了WM_PAINT中,也运行了绘制一个方块代码,但是没有看到方块出现。
此外我还多余地尝试了加入UpdateWindow()函数试图从系统手动调用WM_PAINT,失败。

·我意识到这里没那么简单。于是又回CSDN寻找原因。
在一篇详解WM_PAINT博文中,我找到了问题:

(https://blog.csdn.net/qq_33646230/article/details/50977634)
“系统会在多个不同的时机发送WM_PAINT消息:当第一次创建一个窗口时,当改变窗口的大小时,当把窗口从另一个窗口背后移出时,当最大化或最小化窗口时,等等,这些动作都是由系统管理的,应用只是被动地接收该消息,在消息处理函数中进行绘制操作;大多数的时候应用也需要能够主动引发窗口中的绘制操作,比如当窗口显示的数据改变的时候,这一般是通过InvalidateRect和InvalidateRgn函数来完成的。
InvalidateRect和InvalidateRgn把指定的区域加到窗口的Update Region中,当应用的消息队列没有其他消息时,如果窗口的Update Region不为空时,系统就会自动产生WM_PAINT消息。
UpdateWindow会检查窗口的Update Region,当其不为空时才发送WM_PAINT消息;RedrawWindow则给我们更多的控制:是否重画非客户区和背景,是否总是发送WM_PAINT消息而不管Update Region是否为空等。“

也就是说,窗口中有一个UpdateRegion,指定了窗口有哪些地方要进行更新,这样在WM_PAINT中才能成功重绘更新。
所以我去搜索学习了InvalidateRect()函数:
它依次有三个参数hWnd, IpRect, bErase
分别表示要更新的窗体的句柄、要更新的矩形区域的矩形(结构体指针,为NULL时表示全窗口需要跟新)、指定区域是否要覆盖更新(为true表示要擦除背景重绘,false时不擦除背景)。并且调用InvalidateRect后不需要手动发送WM_PAINT消息。

·在学习了上述知识之后,我在方向键全局变量发生变化的时候,都调用
InvalidateRect(hWnd, NULL, true);
在这里插入图片描述
事实证明,这是正确的:
在这里插入图片描述在这里插入图片描述在这里插入图片描述

·这也解释了一个问题,在我没有详细学WM_PAINT前,手动拖动窗口试图更新窗口时,当使得一部分窗口超出我的屏幕外面后,再拖回来,会发现居然能成功更新,其原因我认为就在于超出屏幕外的地方会自动添加到UpdateRegion中,从而再在拖动窗口引发的WM_PAINT中绘制出方块。

4. 总结:

也算是从底层学习了相当程度的知识,很高兴,比起纯粹听讲,这样自己实验自己试错自己学习效果还是非常不错的,也给与了我许多信心。继续努力!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值