分类: C/C++
2008-08-05 14:01:23
这次写这篇文章,还是重复我上两篇的写作风格,(数据结构篇“老调重提,利用SDK实现迷宫算法”,算法篇,“老调重提,利用SDK实现五子棋”),而现在这篇则是面向对象技术篇,当然还是老调重提!不过我们是利用面向对象技术实现Windows的SDK开发,对于刚开始学习Win32 SDK的VcKbase的朋友们,你们一定可以在此获益!
这次,我会利用面向对象技术实现对Windows窗口的封装!
刚开始编写SDK的程序的时候,都需要写重复的代码,注册窗口类( RegisterWindow ),创建窗口( CreateWindow ),进入消息循环,然后不停地根据消息类型增加消息处理函数!如此重复,解决方法就是Copy And Paste,但是也有很多的不便之处,比如说,我不想这个窗口用这个类名,我不想要这个窗口处理这个消息,哎呀,这个消息处理又忘记加了,真是的,加到哪儿,代码密密麻麻的......当Framework(MFC,OWL,VCL,WTL,Qt......)出现的时候,这才摆脱这些烦劳事情,那时候,我认识Framework后,都不愿意回到SDK的开发了!
拥有Framework后就不等于不需要SDK编程了,Framework是用面向对象的技术把这些基本,重复的开发封装起来(还为开发者提供更加便利,更快,更强的开发了),所以这次我们也要用面向对象的方法对SDK封装,当然,是演示简单的封装和普通的应用,让初学Win32 SDK的开发者对面向对象技术的利用有一个认识,好了,我们开始了!
第一步,我们要封装什么,要找封装的对象!(建立类)
第二步,确定封装对象的特点,特征!(属性)
第三步,确定对象的行为特点,有什么动作!(方法)
Win32 SDK的基本对象是窗口,所以我们这次确定要封装的是一个基本的窗口类,第二步,窗口类具有的特征(这个难,各取所需吧)这个演示程序就是一个窗口程序,所以这个程序的特征是要有Handle(程序的HINSTANCE, HWND),窗口的存在所需要的(WNDCLS,类名...),最后一个,方法当然是窗口要处理各种消息的函数(需要时才用,虚函数在这儿出现)
好了,先看看我们根据这三步设计出来的类!
整个类只有一个成员m_hwnd,和一个回调函数WindowProc,这个类就是作为我们所有的窗口的基类,所有窗口的消息都在这里得到处理,每一个消息对应一个虚函数,当派生类的窗口类需要处理特定的消息时,只要重写虚函数即可!比如,需要处理WM_PAINT消息时,只要派生类中重写OnPaint,即可以处理该消息!
对于一个消息,一个对应的虚函数,听起来很合理,但是在实际中,这是一个很不合理的设计,看过MFC设计的朋友,都应该知道MFC不是这样设计的,它使用的是消息链表!因为虚函数是占空间的,对于每一个类,它需要维护一个虚函数表,当基类存在不需要处理的消息时,它还要维护这样的消息对应的虚函数,是很浪费空间的,所以在实际的开发中,这样的设计是很少采用的,但是我在这里是演示一种对SDK封装的方法而采用这种方式!(只是封装了几个消息,演示目的)
封装后,创建一个窗口只需要几行代码!!
在类中我最主要实现的,也是最重要的,就是要把一个窗口的所有消息封装起来,而这是如何做到的呢?每个窗口都不再存在一个唯一的窗口过程函数,取代的是每一个窗口对象都存在一个唯一的消息处理函数!C/C 中的指针特性帮我们做到了这一点.看如下代码.
通过CreateWindowEx调用时传入当前窗口对象指针,在WM_NCCREATE消息中,就实现了一个窗口类窗口消息处理函数的封装,神不知鬼不觉得把全局消息处理的功能转移到类中,你不再看到以前SDK开发时一大堆全局函数了!!每个窗口类自已负责自已的消息处理!
面向对象的最大优势是继承复用,现在我们已实现了一个非常简单的窗口基类,现在,通过继承这个简单基类,实现一个新的窗口类,这个窗口类有菜单,处理WM_PAINT消息,看看如下继承类:
只需要几行代码,就可以实现原来的SDK的需要几十行代码实现的功能,因为继承已经封装好的基类!
上面对窗口的封装是简单的,但是也说明了对Windows窗口封装的一些要点,也许会对你有一些帮助!!
学习Windows编程,SDK是一个基础,只有在此扎实的基础上,才能在Windows平台上进行技术深耕,这也是我的"老调重提"系列文章目的!