首页 / 软件开发 / C++ / 深入C++ Builder之编写自己的元件-深入分析VCL继承、消息机制(3)
深入C++ Builder之编写自己的元件-深入分析VCL继承、消息机制(3)2009-12-22Aweay题外话很多朋友看了我的前两篇文章后,纷纷来信说能不能介绍一些元件入门的基础知识,因为他们根本找不到相关资料,并询问我是如何知道这些知识的。诚然,网上确实没有这方面的介绍资料,更何况大家是学BCB的,对于Delphi的源代码学习起来更是困难,对于作者来说也不比大家知道多少,我认为最好的方式就是看VCL源代码和去Borland的新闻组提问,至少我是这样解决问题的,希望你也可以。这里是Borland新闻组地址,如果你英文够好,他们基本是有问必答的:forums.borland.com对于那些想学习基础元件知识的朋友,我会在这系列文章的最后部分专门安排2篇文章作为礼物送给你们,一篇是我会实际分析一个专业级元件,来个源代码解剖,把所有细节展示给大家,第二篇是我会实际编写一个简单使用的组件,并介绍全过程,希望大家喜欢。更多消息处理已经写了2篇文章了,怎么还是消息处理?是的,编写元件就是处理消息和表露事件,对于一般的消息处理,前面2篇文章介绍的内容已经足够用了,但是很多时候这还是不够的,比如如果在设计时期你更改了元件的Font属性,而你又想根据字体重新绘制。很明显传统的Windows消息处理其不到丝毫作用,这样的消息通常是WM_XXXX的形式。如果你研究过VCL源代码,你会发现很多CN_XXXX和CM_XXXX这样的消息,如果你要完成我上面提到的消息处理,这些消息可以帮助完成任务。其实,VCL存在一些非API消息以供其内部使用,为什么要这样做呢?这要从WM_COMMAND & WM_NOTIFY消息说起,我们说WM_COMMAND消息并不是直接发给实际产生消息的窗体,而是发送到它的父窗体。但是父窗体几乎不可能用通常方法处理这些根本不知道如何处理的消息,于是父窗体把这个消息加上CN_BASE在分发到实际的子窗体中,然后由实际的子窗体处理。比如TBitBtn元件为了在按钮表面绘制图象,处理了CN_DRAWITEM消息,这个消息处理函数是这样写的:FCanvas.Handle := DrawItemStruct.hDC; R := ClientRect;
… //省略一部分 if IsDown then OffsetRect(R, 1, 1); TButtonGlyph(FGlyph).Draw(FCanvas, R, Point(0,0), Caption, FLayout, FMargin, FSpacing, State, False, DrawTextBiDiModeFlags(0));
if IsFocused and IsDefault then begin R := ClientRect; InflateRect(R, -4, -4); FCanvas.Pen.Color := clWindowFrame; FCanvas.Brush.Color := clBtnFace; DrawFocusRect(FCanvas.Handle, R); end;