MFC我没用过,但一理通,百理明,从其他语言的用法,也可以知道基本的原理,根据原理,去追索资料,总能找到。
所谓“动态生成控件”,无非是在程序运行时向某个“容器”(Container类型的控件)添加控件,窗体(Form)就是一个最基本的容器,表格(Grid)也是,这是一类可以向其中添加物件的容器。凡是这类容器,必然有一个追加对象(AddObject)的方法,比如某个Form的实体ID叫Form1,那么通常调用Form1.AddObject()方法,就是向这个容器添加参数中指定的控件实体,因此关键是在哪个容器中发出AddObject()指令,你想向哪个容器加控件,就把这个容器的动态添加控件的方法找出来(一定有的,因为这是该控件设计的必需品)。在Visual FoxPro中这是AddObject方法,在 C#中这是.AddControl()方法。通过Add操作,所谓动态生成的控件ID,就是把从祖先到父亲及自己的ID串连起来,标识出有继承关系的ID,构成一条控件链,供操作系统查寻使用,Windows自己维护这种对象数据库。
以上是运行时的动态生成原理,在可视化的设计模式IDE中,是IDE执行这种Add操作,把控件动态添加到对应的地方,这时,它向你隐瞒了真实的代码步骤,因此,很多依靠可视化(Visual)编写程序的人,就很难了解在没有IDE环境下如何仅靠代码动态添加控件,从而产生“面向对象编程就是用鼠标拖拖拉拉”的错觉。事实上,我用Visual FoxPro编程,就从来不使用这种可视化编程模式,所有控件都是在代码中生成的,因此很清楚这类东西的运作机制。用这样的经验,在上也看到同样的做法,故此基本上可以确定MFC也必定是这样。事实上,无论Visual FoxPro,还是和C#、MFC,在根本底层上,都是微软的那一套运行时库,它们编程出来后所执行的效果,全部是同一个控件类产生的(比如Form控件,Visual FoxPro是很古老的产品,但现在用它的Form控件生成的窗体,却呈现出Win7窗体的半透明标题栏和边框模式,可见实际执行的就是Windows当前版本的控件)。所以,在底层原理上,必定是相通的。
你按照这样的思路,在MFC文档中查找看看,必定有相关资料。关键之处无非是两点:首先要确定你只能向容器性质的控件中动态添加控件,你可以把TextBox添加到Grid中,但无法在TextBox中再添加一个TextBox,把控件的性质搞清楚;其次是找到容器类添加子类的方法(Grid控件中必定有,而TextBox控件中肯定没有),看文档。动态生成的控件,一定是用new方法在堆上申请的一个对象,然后把这个对象的句柄返回给你,添加在它的父类的孩子清单上。
其实,在传统C++中写面向对象的控制台程序,也是用这种思路识别对象树,就如链表的原理一样,总有一个指向父项的标识和指向后裔的标识,不管那是不是可视化的对象,只要有包容关系,就一定要设计这样的字段,因为这是逻辑的要求,闭着眼睛都把它先写下来,至于用不用得到、如何用,以后再说,缺了必需品,以后伤筋动骨的可能性就越大,只要你挂着这么一个“未使用”的东西,随时都会提醒你有什么未做完,自然会想办法把它做了。因此设计初期就要审慎,对常用的类,要通过大量的小程序应用来测试,稳定下来之后才能应用于大系统。花两三年的时间,积累这么一套自己的工具库,你以后编程就轻松多了。把精力和时间花在这方面,好过就题做题。不想把组件代码的功能扩展到最大适用范围的,那是没打算以后从事这行当的,没意识就是没资质、不适合,以后做重复代码的疲劳,很快就会把你的兴趣消磨净尽——不要把兴趣当职业,这是社会上很流行的忠告了。
【题外话,以我对Visual FoxPro的理解,在本机程序范畴,它强大到足以应付一切可能的需要,除了不能在Web浏览器上运行自己的代码,它可以把IE的内核作为控件嵌在自己的界面上故可以浏览网页,它有API接口可以做到与系统最底层密切合作,而使用却比VC轻松得多,故此我说不需要用C/C++编写Windows程序,不必要花那些精力。在内部机制上,我现在已经看出C#有VFP的影子,除了提供更多更新的功能,在基本原理上竟然是那么相似。好像从什么地方看到,似乎微软把VFP开发团队的核心人员调到C#开发部了。以下是我用VFP提取的点阵字模的图案,如果用C实现这样的效果,耗费的精力要多很多(连空行算也只有130行),因为以前就是要从现成的点阵字库中切割偏旁部首组合GB2312编码中没有的汉字传输到LED显示屏中显示,要看到字模的数据影像才好做功课,曾经写过那样的东西。为了节省内存,在英文DOS下,就是用这样的东西显示中文的,这就是CCDOS的原理。在现在,如果要在控制台下显示特殊的字体,而系统又没有对应的等宽字体库,就可以用同样的办法做,不必总是单调的宋体字。】
图片附件: 游客没有浏览图片的权限,请
登录 或
注册
[
本帖最后由 TonyDeng 于 2012-3-28 04:27 编辑 ]