快速业务通道

深入C++ Builder之编写自己的元件-深入分析VCL继承、消息机制(2)

作者 佚名技术 来源 程序设计 浏览 发布时间 2012-06-30

DYNAMIC函数

在上篇文章我们讲到了如何绘制元件,但是光绘制元件还是不够的,一个元件不光要有样子,还要能够处理、相应用户输入,这就需要我们来处理键盘鼠标事件。

处理键盘鼠标事件同样像我们处理系统消息一样,比如WM_KEYDOWN等这样的消息,所以你可以同样像在Form中处理消息那样重载WndProc或者编写消息映射宏,所有的这些方法都可以用到元件中,但是我们没有不用,也没有必要这么做。VCL已经提我们预留了很多接口函数,我们只需要重载相应虚拟函数就可以完成相应事件的处理。

如果你要处理鼠标事件,那么你需要重写下列函数:

MouseDown

MouseUp

MouseMove

Click

如果你需要处理键盘,那么你需要处理下列函数:

KeyPress

KeyDown

KeyUp

对于键盘虚拟函数,你需要注意派生类必须继承自TCustomeControl(直接或间接,准确的说,也不一定)才能使用上面的虚拟函数。

上面的函数看起来和我们在设计Form时的函数差不多,但是他们有一个明显的差别,如果你重载他们似乎不是那么容易,如果你看VCL源代码,它只写一个overide关键字来标示函数属性,但是在C++里这样就不行了,为什么呢?

我们先来看一下在VCL中的源代码:

procedure KeyDown(var Key: Word; Shift: TShiftState); dynamic;
   procedure KeyUp(var Key: Word; Shift: TShiftState); dynamic;
procedure KeyPress(var Key: Char); dynamic;

基本上所有的这些虚拟(动态)函数都是这样申明的,可以在C++并没有dynamic这个关键字啊?为了解释这个问题,我们先来了解一下什么时dynamic函数:

在Delphi中,函数有virtual和dynamic两种多态方式,对于virtual和我们C++中的virtual没有区别,而dynamic则不一样,dynamic仅维护一份虚拟方法表,当一个基类有多个多态函数,而这个基类又有可能被多次继承的时候,使用dynamic申明的函数可以减少代码长度,不过dynamic和virtual的行为都是差不多的,virtual的速度要比dynamic快一些,dynamic要比virtual代码长度小。

如果你想深入研究一下这个问题,可以参考以下文章:

http://www.csdn.net/develop/Read_Article.asp?Id=14729

或者去borland的新闻组提问,一定能得到满意的答复。

我们知道在标准C++中并没有dynamic关键字,所以为了C++ Builder能使用VCL的类,Borland做了扩充,我们可以直接使用DYNAMIC宏来实现动态函数,所以如果我们要在自己的派生类中重写这些消息处理函数,我们需要这样:

DYNAMIC void __fastcall MouseMove(Classes::TShiftState Shift, int X, int Y);

现在我们已经能画出元件,能处理元件的消息,基本上我们已经可以编写一些简单的元件了。在继续下面的内容之前,也作为这篇文章的结束,我们来实际编写一个简单的元件。这里我们假设你已经有了一定编写元件的经验,如果你看不懂相应代码也没有关系,我会在后面的文章做详细讨论。

下面时我以前帮网友写的一个简单的矢量绘图板的元件的源代码,它实现可以在元件上画出矢量直线,包括选取和重新调整:

(h头文件)

//---------------------------------------------------------------------------
#ifndef VecCanvasH
#define VecCanvasH
//---------------------------------------------------------------------------
#include <SysUtils.hpp>
#include <Classes.hpp>
#include <Controls.hpp>
#include "Shape.h"
typedef void __fastcall (__closure *THoverShapeEvent)(TObject* Sender,int Index);
typedef void __fastcall (__closure *TShapeSelectedEvent)(TObject* Sender,int Index);
enum ToolType{ttSelect,ttLine,ttRect};
//------------------------------------------------------------------------

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号