回复 9楼 有容就大
主要原因是你没有面向对象的编程思维,采用的基本上是面向过程的方法。看看如下问题:
1.你现在知道鼠标移动时,它激发的消息发送到哪里、你能接收它吗?
2.如果你能随时检测到鼠标的位置,那么就可以设置鼠标移动的事件代码,当鼠标坐标符合特定条件时,就自己发送一条消息,设置某个全局变量。
3.上面第2步的全局变量,正是控制现在要处理哪个格子的ID,相对于对象句柄。
有了上面3个前提,你就可以把棋盘划分为90个单元格,每个单元格都是一个对象(我不知道你是否有使用Image Control那样的经验),而这90格对象都是从同一个类中生成的实例,即90个对象的代码都是集中在一起的,相当于你一段代码同时控制着90个不同的格子,这才是面向对象的真正作用,是你用面向过程思维很难处理的。
只要你前面的鼠标移动事件设定某个单元格为活动,代码类似Grid[i,j].SetFocus,就表示此时类代码中的处理对象是实例Grid[i,j],此时切换这个单元格的图像,就改变了这个单元格的棋子,而不会影响到其他棋子。
这样,你所要做的,就是设计一个Image Control,它是一个60*60像素的方框,属性有诸如Top、Left、Width、Height(棋格位置和尺寸)、BackImageUrl(棋格背景图)、ChessPieces(棋子代码用于提取棋子)、Actived等等一切需要用到的东西,想到什么就加什么。用这个类创建Grid[10,9]共90个实例,初始化成一张棋盘。注意这时棋格的位置是非常有规律的,鼠标活动事件函数极容易知道自己落在哪个格子上,一落下去,就可以设置对应格子的Grid[i,j].Actived = True。处理的过程,就由鼠标移动事件来控制,只要鼠标所在的棋格有棋子,有可以被提起、改变棋子,这个棋格自己改变棋子的图案,用自己的位置尺寸来显示,根本不用管它实际上是棋盘上的哪一个格子,也不需要知道自己的尺寸到底有多大,只要显示棋子的函数把读入的图像BitMap缩放到属性标注的Width*Height就可以了。
这样,棋局处理逻辑和显示界面就分离了。不管将来你把棋子改成怎样的图案、棋格的尺寸如何变化,都不会影响逻辑处理过程。
Image Control的实质,不过是窗体中的子窗体,可以在子窗体上面放置图案,它本身也有一系列跟窗体一样的消息感应机制,做到最前面那3点前提,就知道如何去做(其实知道子窗体,就算不用鼠标感应,子窗体自己本身也有鼠标MouseMove消息,它自己知道是否鼠标进入自己的范围,连鼠标移动处理函数都不用,这看你了解什么手段了)。实际上,你平时就应该封装一系列这样的控件。可以在做这个项目的过程中开始做这些控件,也可以摸索现成有什么控件可供使用,参照一下别的语言、别的环境中有什么好用的方法,用自己懂的方法仿做一个。你没见过Image Control那样的东西,自然不知道有这样的思路,说到底,还是应该开阔眼界为是。在别的高级语言中,只要是GUI编程,基本上都有这种控件可供使用,在这方面,死守C、API是没有必要的,你再做得来,也不过是重复别人已经做得很好的东西罢了。精力应该花在思考上面所说那样的思路上,而不是花在如何把BitMap显示到什么地方那样的细节上。
没有高级的应用基础,就着手碰底层,当然什么思路都没有。只要高层应用无法解决的东西,才需要考虑底层辅助,而现实中这种需求极少,何况你连高层应用的经验都没有。
[
本帖最后由 TonyDeng 于 2012-5-14 21:06 编辑 ]