<b>深化C++ Builder之编写自己的元件-深化解析VCL担当、消息机制(3</b>[VC/C++编程]
本文“<b>深化C++ Builder之编写自己的元件-深化解析VCL担当、消息机制(3</b>[VC/C++编程]”是由七道奇为您精心收集,来源于网络转载,文章版权归文章作者所有,本站不对其观点以及内容做任何评价,请读者自行判断,以下是其具体内容:
题外话
很多朋友看了我的前两篇文章后,纷纷来信说能不能介绍一些元件入门的底子知识,因为他们根本找不到相关资料,并询问我是若何知道这些知识的.当然,网上确切没有这方面的介绍资料,更何况大家是学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;
FCanvas.Handle := 0;
可以看出这和普通处理Paint的办法差不多,其实都是在HDC上作图.假如你学习过SDK的话,其实我们可以自己处理WM_NOTIFY消息来处理那些由控件产生的消息,只不过VCL替我们封装了一下罢了.
还有一些消息是VCL内部控件而产生的,这类消息普通是CM_XXXX的格局,比方CM_FONTCHANGED这个消息就是当字体改变的时刻触发,具体的定义你可以在Controls.pas文件中找到,这里就不再具体介绍了
关于上面的CM_FONTCHANGED消息,普通是这样处理的:
procedure TBitBtn.CMFontChanged(var Message: TMessage);
begin
inherited;
Invalidate;
end;
通过上面的谈论,得出一个结论,全部CN/CM消息都可以自己处理,但是他们没有对应的虚函数,所以我们只好用老办法,所以消息映射宏在这里是最好得办理筹划,比方像这样:
BEGIN_MESSAGE_MAP
VCL_MESSAGE_HANDLER(CN_DRAWITEM, TWMDrawItem, CNDrawItem)
END_MESSAGE_MAP(TCustomControl)
Void __fastcall CNDrawItem(TWMDrawItem Msg);
定义自己的消息
在上篇文章的完毕,我示范了一段元件代码,假如你还记忆犹新的话:
typedef void __fastcall (__closure *THoverShapeEvent)(TObject* Sender,int Index);
typedef void __fastcall (__closure *TShapeSelectedEvent)(TObject* Sender,int Index);
能否还记得上面的代码?
以上是“<b>深化C++ Builder之编写自己的元件-深化解析VCL担当、消息机制(3</b>[VC/C++编程]”的内容,如果你对以上该文章内容感兴趣,你可以看看七道奇为您推荐以下文章:
本文地址: | 与您的QQ/BBS好友分享! |