当前位置:天才代写 > tutorial > C语言/C++ 教程 > 深入C++ Builder之编写本身的元件-深入阐明VCL担任、动静机制(1)

深入C++ Builder之编写本身的元件-深入阐明VCL担任、动静机制(1)

2017-11-05 08:00 星期日 所属: C语言/C++ 教程 浏览:907

副标题#e#

这篇文章提及内容大概各人已经在许多处所看到过了,作者也是如此,只不外还看了许多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担任


#p#副标题#e#

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();
  }
}

 

    关键字:

天才代写-代写联系方式