当前位置: 首页 > 学习 > 电脑学习 > 程序设计 > C++ > 消息与API > 正文

深入C++ Builder之编写自己的元件(1)

http://www.zk168.com.cn  招考学习网 2006-4-11 5:11:04
-----------------------------------------------------------[交流]-[打印]-[发送]-[收藏]--
深入C++ Builder之编写自己的元件-深入分析VCL继承、消息机制(1)

这篇文章提及内容可能大家已经在很多地方看到过了,作者也是如此,只不过还看了很多VCL源代码,加上自己实际编写元件的经验,拼凑了这么一篇文章。所以所有言论都是个人观点、经验的描述,仅供参考。

你可转载,拷贝,但必须加入作者署名Aweay,如果用于商业目的,必须经过作者同意。

系统要求

如果你想一起跟着做的话,那么你应该看看这里,否则你可以直接跳过。
C++ Builder6 + updata4  (上帝造人的工具,以下简称BCB)
Windows2k or higher (必要)
作者强烈建议你使用WinNT,BCB在Win9x下有非常多的问题,而且非常不稳定,就算你不在乎这个,还有一个非常致命的问题,BCB的帮助文件在Win9x下显示不完全(因为BCB的帮助索引关键字数量超过Win9x的限制),这样非常难于参考帮助。
Delphi6 :( (必要)
什么?是不是写错了,完全没有写错,如果你要深入VCL查看源代码的话,在没有比用Delphi6更合适的了,在全部安装Delphi6后,把VCL Source的目录加入Search Path中,这样你可以在编辑器中按住Ctrl键,点击鼠标直接跳转到源代码处非常方便,比什么grep好用多了。

起步

对于VCL的消息机制,大家可以参考CKER的
http://www.csdn.net/develop/read_article.asp?id=8131

重复的内容我就不介绍了,但是对于编写元件来说上面的消息机制还是很模糊,而且很多时候并不是用那些方法来处理消息的,还有就是元件特有的CM_XXXXXXXX消息如何处理呢?如何加入自己的事件呢?这些问题我会在后面的讨论中做详细介绍。

站在巨人的肩膀

编写元件的第一件事情就是确定我们从那里继承的问题,选取一个好的祖先类是编写一个好的元件的第一步,那么到底如何选取他山之石呢?一般性的规则是这样的:
1.对于有界面的显示的,需要处理键盘事件的,又不是容器的组件从TCustomControl继承
2.对于有界面的显示的,需要不处理键盘事件的,需要处理鼠标事件的从TGraphicsControl继承
3.对于没有界面显示的,类似与TOpenDialog/TXpMenu这样的控件从TComponent继承
4.如果你想扩展某个指定的控件,比如TPanel,你最好从TCustomPanel继承,而不要从TPanel直接继承。

注意上面第4条规则,基本上所有组件都有TCustomXXX的父类,这也是VCL鼓励的继承对象,原因在于你可以定制元件属性的可见性,最重要的是他们的构造函数和析构函数是虚拟的。

这篇文章主要针对1,2规则的元件进行介绍,3,4相对简单就不作深入讨论了。

画出自己

元件要显示在窗体上,必须以一定的样子出现,那么可定要画出自己,大家都知道处理WM_PAINT消息就可以了,从CKER的文章里,我们可以得出很多方法来处理这个消息,比如:
__fastcall WndProc(TMessage msg)
{
  switch(msg->msg)
  {
    case WM_PAINT:
      //我们的处理代码
  ...
}

或者干脆用消息映射的宏,但这些都不是最好的方法。

从TControl以后的组件都有Paint这个虚拟方法,我们只要重载这个方法就可以自动绘制,相当于处理了WM_PAINT,这是因为:
procedure TGraphicControl.WMPaint(var Message: TWMPaint);
begin
  if Message.DC <> 0 then
  begin
    Canvas.Lock;
    try
      Canvas.Handle := Message.DC;
      try
        Paint;
      finally
        Canvas.Handle := 0;
      end;
    finally
      Canvas.Unlock;
    end;
  end;
end;
以上代码片断说明了这一点,据我所研究过的专业级组件都是通过重载这个函数来绘制自己的。

注意上面的代码片断就是用我上面提到的方法(装delphi6)按了几次鼠标左键得到的,是不是很实惠,^_^。

在Paint方里我们可以自由绘制,在后面的文章里我会交大家如何高效率绘制。

在很多时候,我们需要重绘自己,比如我前几天给网友做的划线的组件,当线的宽度改变时我们必须重绘自己,否则无法反映属性的改变,我见很多朋友使用repaint()方法,这也不是最好的方法,我们应该用Invalidate(),为什么?留给大家看源代码吧,就算复习上面的知识了。
代码演示:
void __fastcall TLine::SetLineWidth(int value)
{
  //TODO: Add your source code here
  if(FLineWidth!=value)
  {
    FLineWidth=value;
    Invalidate();
  }
}
-----------------------------------------------------------[交流]-[打印]-[发送]-[收藏]--
最新入库:
 
·实质、过程及意义——阿多尔诺“否定的辩证法”探微
·从Ontology的译名之争看哲学术语的翻译原则
·论马克思主义哲学经典的解释——解释学方法及其在马克
·中国哲学当前的核心与周边问题
·和合学与21世纪文化价值和科技
·中国文化的和合精神与21世纪
·宗教之间理当相互宽容
·上半个世纪的自由主义
·殷周至春秋时期神人关系之演进
·大学之道:构建以“三纲八目”为核心的道德修养体系
相关内容:
 
·21世纪以煤和天然气为原料的C1化学
·BOG压缩机在液化石油气基地的应用
·OECD主要国家软件业发展概况
·英美CPA管理模式及其启示
·沙角C电厂事故顺序记录的通道组态分析及整改
·LFCB-102型微波分相差动保护的应用
·沙角C电厂厂用电结线分析
·基于PB6和ORACLE8开发“劳动信息管理系统”
·利用TDC组件实现对WEB页面的交互操作
·TCP/IP在网络中的高效配置
网友点评:
 
会员名称:
密码:匿名 ·注册·忘记密码?
评论内容:
(最多300个字符)
  查看评论
友情提醒:
 1.库中的资料大都来自互联网、网友上传、各类书籍,在录入的过程中难免会出现错误,恳请网
 友来信指正!
 2.如果网友在本库中未能找到所需要的材料,请登陆到我们的论坛《招考学习网》版块!
 3.考友想加入招考学习网的编辑部,请发信到XueXiWang#Gmail.com(#改为@)附带个人简历
 4.如需转载请注明出处及作者,谢谢合作!
 5.如果您有更好的建议或意见请EMAIL:XueXiWang#Gmail.com (#改为@)
 6.凡标题中有注有“[NO]”字样均不含答案且答案整理中.
 7.如本库中转载文章涉及版权等问题,请相关网站或作者在两周内发邮件通知(EMAIL:  XueXiWang#Gmail.com (#改为@))我们,我们接到通知后立即删除该文章及链接!
你问我答 更多>>