14

我正在寻找一些代码,可以轻松地将许多事件处理程序分配给单个对象事件......我的插件架构非常需要它,所以我实现了一些替代品,但是我不喜欢我的解决方案,所以我想知道你的想法/解决方案/提示是什么......我的解决方案只是一个列表, eventName: string; proc: TMyEventProc; 其中包含 TMyEventProc 接受两个参数、sender 和 eventData:pointer 之类的项目。根据事件的名称,eventData 指向不同的记录/对象。

不幸的是,这需要声明许多记录作为参数传递。该方法也很慢,并且需要在“真实”事件被命中时调用所需的“回调”。

4

4 回答 4

11

我实现了一个适用于几乎任何版本的 Delphi 的解决方案——它最初是在 Delphi 7 中实现的,虽然我没有在早期版本中测试过它(但如果你自己使用 Delphi 7,那么这就是你所需要的知道,对吧?)。:)

iirc 这至少部分是 Allen Bauer 帖子的灵感来源。您可以在一些视频中看到我的实现,并从我的博客下载代码:

您感兴趣的帖子被标记为“多播”。最终代码的下载链接可在这篇文章中找到。

在我的方法中,您从 TMultiCastEvent 派生一个类。您的派生类所要做的就是实现一些简单的类型安全保护,以添加、删除和调用具有特定签名的事件。

TNotifyEvent 的实现 - procedure(Sender: TObject) - 提供了“让你继续”的实现(我最“有用的”多播事件是简单的通知)以及如何为特定的多播事件类派生的示例事件签名。

一旦你有了你的多播事件类,你就可以使用常规的“事件处理程序”与多播版本互换,例如给定一些带有多播 On_Click 事件的虚构按钮类(我采用了在事件中插入下划线的约定将其标识为多播的名称,而不是常规的“单播”事件):

将处理程序分配给单播单击事件的代码:

  Button.OnClick := MyClickHandler;

可以直接将相同的处理程序添加到多播通知事件:

  MultiCastButton.On_Click.Add(MyClickHandler);

我的实现还包括许多改进,例如能够禁用事件并在实现对象被销毁时自动从处理程序中删除处理程序(这涉及少量的内务处理,如果需要可以忽略,但在某些情况下可能很有用情况)。

所有这些都在我的博客文章中进行了描述和演示。

享受。:)

于 2009-09-09T00:37:33.990 回答
2

Allen Bauer 有一篇关于多播事件的博客文章可能会有所帮助。不过,它仅适用于 Delphi 2009 或更高版本。

编辑:如果您仍在 D7 上,如果您不需要太多不同的事件签名,您可能仍然可以完成这项工作。尝试查看 Allen 的代码,看看是否可以将其调整为非通用解决方案。

于 2009-09-08T23:04:59.740 回答
1

如果你正在实现一个插件系统,我认为,你不能仅仅使用事件处理程序——不管它是否是多播。我建议看看观察者模式。在多播事件附近可能听起来有点过于冗长,但至少在您需要时更加灵活。

于 2009-09-09T10:41:36.920 回答
0

您可以为此使用观察者设计模式。这是一个示例 delphi 实现:http: //blogs.teamb.com/joannacarter/2004/06/30/690

于 2009-09-09T11:16:13.973 回答