我应该在 Delphi 而不是 C++ Builder 中编写组件吗?如何向组件添加事件?

Posted

技术标签:

【中文标题】我应该在 Delphi 而不是 C++ Builder 中编写组件吗?如何向组件添加事件?【英文标题】:Should I write components in Delphi instead of C++ Builder? How do I add events to a component? 【发布时间】:2012-09-11 17:13:34 【问题描述】:

我使用 C++ Builder (XE2),我需要开发一些在 Delphi 中也可以使用的 VCL 组件。据我了解,C++ Builder 支持 Delphi 代码和 Delphi 组件,但反过来不支持?如果是这样,最好开始用Delphi编写,这样我就不会做双重工作了?

我的问题的第二部分更具技术性;我知道如何在 VCL 组件中添加属性,但不知道如何添加事件。有人可以给我一个例子吗(无论是 Delphi 还是 C++ Builder)。

谢谢。

【问题讨论】:

欢迎来到 Stack Overflow。请注意,您可以发布的问题数量没有限制,因此您不应感到有压力将所有问题包含在一个帖子中。您关于语言偏好的问题与您关于事件属性的问题无关,因此您应该将它们单独发布。 【参考方案1】:

据我了解,C++ Builder 支持 Delphi 代码和 Delphi 组件,但反过来不支持?

在源代码级别 - 是的。 但是,如果您选择无源分发您的库 - BPL+DCP+DCU - 那么这无关紧要,除了可能存在一些小的不兼容问题,例如 Delphi 缺少 [] 运算符和 C++ 缺少虚拟重载构造函数。

事实证明这个估计是错误的。阅读下面雷米的评论


最接近您的示例 ov 事件是 VCL 本身,源代码通常随 Delphi 一起提供。如果您有没有 VCL 源的 Delphi Starter/Trial - 然后获取任何开源 VCL 库或组件。例如 JediVCL 或基本上几乎任何带有源的 VCL 组件。例如,任何"FWS" (Free with sources) 组件 99% 使用事件。

大多数基本和广泛使用的事件通知类型——例如 TButton.OnClick、TForm.OnCreate 等等——是 TNotifyEvent

为该类型打开Delphi Help。滚动到“另请参阅”并在此处查看两个链接。

Procedural types 类似于 C 中的 int (*f)(void)。 Events creating manual

【讨论】:

C++Builder 无法创建供 Delphi 使用的 DCP/DCU 文件。它只能生成 BPI/BPL 文件。在 C++ 中创建可以在 Delphi 中静态使用的包是不可能的,但它可以创建可以动态使用的包。如果您想同时支持 Delphi 和 C++Builder,请仅在 Delphi 中编写组件并打开其选项以生成 C++ 输出文件。 谢谢雷米。这是我的计划。【参考方案2】:

如: (从about.delphi.com借来的代码)

type
  TState = (stStarted, stStopped);
  TStateChangeEvent = procedure
  (Sender : TObject; State : TState) of object;

  TThirdComponent = class(TSecondComponent) // or whatever
  private
     Private declarations 
    FState  : TState;
    FOnStart,
    FOnStop  : TNotifyEvent;
    FOnStateChange  : TStateChangeEvent;
  protected
     Protected declarations 
  public
     Public declarations 
    constructor Create(AOwner : TComponent); override;
    destructor Destroy; override;
    procedure Start; override;
    procedure Stop; override;
    property State : TState
      read FState;
  published
     Published declarations 
    property OnStart : TNotifyEvent
      read FOnStart
      write FOnStart;
    property OnStateChange : TStateChangeEvent
      read FOnStateChange
      write FOnStateChange;
    property OnStop : TNotifyEvent
      read FOnStop
      write FOnStop;
  end

那你就可以了

procedure TThirdComponent.Start;
begin
  inherited; 
  FState := stStarted;
  if Assigned(OnStart) then OnStart(Self);
  if Assigned(OnStateChange) then 
    OnStateChange(Self, State);
end;

【讨论】:

能否请您解释一下这部分:属性 OnStart : TNotifyEvent read FOnStart write FOnStart; 那里到底要解释什么? TNotifyEvent 是指向过程google.ru/… 的指针,您要么将其留空,要么将过程的地址分配给它。 int (*f)(void) 如果我记得一些 C 有趣的是,当您在 Delphi 官方文档(上面的链接)中阅读有关 TNotifyEvent 的信息时,还有另见部分。第二个链接是手册“如何创建事件) 澄清一下; * 你创建一个 ThirdComponent 的新实例,定义一个过程,其参数与 TStateChangeEvent = procedure (Sender : TObject; State : TState) of object;TNotifyEvent 中定义的参数相同;将新定义的过程分配给相应的属性。 newInstance.onStateChange := ThingsToDoOnStateChange; 当您调用 newInstance.Start 时,您的过程将到达 ThirdComponent.Start 方法中定义的相应位置。 谢谢。将尽快实施。

以上是关于我应该在 Delphi 而不是 C++ Builder 中编写组件吗?如何向组件添加事件?的主要内容,如果未能解决你的问题,请参考以下文章

Delphi中在Edit这个控件里怎么让光标始终停留在数据后面?而不是每个更新数据返回前面

CMake configure_file没有源代码构建

发布delphi程序(build with runtime package)要带哪些文件?

Visual C++ Build Tools 2015——安装失败?

如何在 Delphi 中将浮点数转换为字符串,指定有效数字,而不是十进制数字(而不是 G 格式)

C++ Builder / Delphi 2010 应用程序清单模板