windows SDK模拟游戏钢琴的实现(二)
昨天晚上失眠了,于是一直在想实现GDI的一个效果:首先绘制10个相连的矩形,当鼠标移到某个矩形的时候,自动填充那个矩形的背景颜色为灰色,移开的时候恢复原来的白色。当只有一个矩形的时候,当然不是一件难事。但是当有10个矩形的时候,问题就产生了。首先先看一下代码:
下面来看一个这个处理鼠标移动的操作:
一运行问题就来了:只有当鼠标移到第一个矩形的时候才会产生效果,而移到后面9个的时候根本没有产生任何效果!!
我把上面for 循环的 初始条件的 i=0 改成 i=1,这下子更加糟糕了:连第一个矩形都不能产生效果了。看来问题就是在这里了。
那么为什么会不起作用呢?
向华哥请教后,终于发现端倪了:
我是什么时候把刷子的句柄选入设备环境里面的呢? 就是上面的当 Flag[i] == 1 的时候 ,一旦选入了以后,那么后面所有的矩形绘制的时候用的都是灰色的刷子。
所以首先在WM_PAINT消息里面 添加选择刷子的消息:
for (i = 1; i <NUM; i++)
{
if (Flag[i] == 1)
SelectObject(hdc, hBrush);
rect[i].xLeft = rect[i-1].xLeft + 20 ;
rect[i].xRight = rect[i-1].xRight + 20 ;
rect[i].yTop = rect[0].yTop ;
rect[i].yBottom = rect[0].yBottom ;
Rectangle(hdc, rect[i].xLeft, rect[i].yTop, rect[i].xRight, rect[i].yBottom);
}
但是麻烦又来了:如果第i个是灰色的,那么从第i+1个开始后面的所有矩形都变成灰色的了由于发送了10条重绘消息,说明鼠标移动到某个点的时候整个屏幕刷新了10次!!相当于10个矩形总共画了10次!!现在问题应该很明显了:重新绘制出来的窗口把原来的窗口效果给覆盖掉了,如果说原来第i次第i个矩形是灰色的,那么第i+1次的时候又被覆盖成白色的了!!!
而且我的i设置的时候不是全局变量,所以每一个进入VM_PAINT消息的时候i都是0
好了,错误发现以后,我们就可以改正了。首先是逻辑上的修正:
每次重新绘制整个窗口的时候都先把10个矩形画出来,然后在根据鼠标移动传过来的信息判断哪一个矩形应该被重画。
逻辑清楚了以后,写起来就简单了。
我把(一)中的声音效果再加进来,再添加鼠标左键点击发出声音,最终的代码如下: