Delphi中事件处理程序的Invoke方法

Delphi中事件处理程序的Invoke方法,delphi,Delphi,下面是一个用C编写的代码示例,该代码在proc COM对象中使用SDK 我已经创建了一个类:TSwitcherMonitor,现在我必须将回调函数分配给我的对象属性:OnSwitcherDisconnected属性。我在C中有一个调用示例,说明中提到了lambda表达式的双重使用。我在谷歌上搜索过这个,似乎Delphi没有lambda表达式 以下是C中的调用: 问题1:在Delphi中,有一种方法可以使用invoke方法执行相同的操作,或者我们必须以不同的方式执行 //Create callba

下面是一个用C编写的代码示例,该代码在proc COM对象中使用SDK 我已经创建了一个类:TSwitcherMonitor,现在我必须将回调函数分配给我的对象属性:OnSwitcherDisconnected属性。我在C中有一个调用示例,说明中提到了lambda表达式的双重使用。我在谷歌上搜索过这个,似乎Delphi没有lambda表达式

以下是C中的调用: 问题1:在Delphi中,有一种方法可以使用invoke方法执行相同的操作,或者我们必须以不同的方式执行

//Create callbacks object
  m_switcherMonitor := TSwitcherMonitor.Create(Application.Handle);
  // note: this invoke pattern ensures our callback is called in the main thread. We are making double
  // use of lambda expressions here to achieve this.
  // Essentially, the events will arrive at the callback class (implemented by our monitor classes)
  // on a separate thread. We must marshell these to the main thread, and we're doing this by calling
  // invoke on the Windows Forms object. The lambda expression is just a simplification./
  m_switcherMonitor.OnSwitcherDisconnected += new SwitcherEventHandler((s, a) => this.Invoke((Action)(() => SwitcherDisconnected())));
问题2:我唯一想做的,就是在使用SDK时有一个有效的回调。我的TSwitcherEventHandler声明正确吗

作为参考,这里是我的TSwitcherEventHandler声明和TSwitcherMonitor类:

Type
{TSwitcherEventHandler}
  TSwitcherEventHandler = procedure(const sender: TObject; const args: TObject) of object;

{TSwitcherMonitor}
  TSwitcherMonitor = Class(TComObject, IBMDSwitcherCallback)
  private
    FHwnd: HWND;
    FSwitcherDisconnected: TSwitcherEventHandler;
  published
    constructor Create(hWnd: HWND);
  public
    function Notify(eventType: _BMDSwitcherEventType): HResult; stdcall;
    property OnSwitcherDisconnected: TSwitcherEventHandler read FSwitcherDisconnected write FSwitcherDisconnected;
  end;

implementation
{ TSwitcherMonitor }
constructor TSwitcherMonitor.Create(hWnd: HWND);
begin
  FHwnd:= hWnd;
end;

function TSwitcherMonitor.Notify(eventType: _BMDSwitcherEventType): HRESULT; stdcall;
begin
  if eventType = bmdSwitcherEventTypeDisconnected then
    if assigned(FSwitcherDisconnected) then
      FSwitcherDisconnected(self, nil);

  result := S_OK;
end;

我不是德尔福专家,但对于舒尔来说,正如许多人所说,德尔福摇滚

C行:

m_switcherMonitor.OnSwitcherDisconnected += new SwitcherEventHandler((s, a) => this.Invoke((Action)(() => SwitcherDisconnected())));
可以在Delphi中进行简单的翻译,如下所示:

m_switcherMonitor.OnSwitcherDisconnected := switcherMonitor_OnSwitcherDisconnected;

现在我的示例应用程序开始工作。Delphi做一些指针自动作业,在Delphi中转载C或C++代码时,只需写得简单,Delphi就可以完成任务。一开始,当我们试图理解这些东西是如何工作的时候,使用这种黑魔法是很奇怪和困难的,但是德尔福确实是一个真正的RAD

很难看出C是从哪里来的。这不是一个纯粹的德尔菲问题吗?Delphi的匿名程序相当于C lambdas。@Heffernan,圣诞快乐,C是我在C中看到的示例,我不理解事件句柄赋值的invokeaction部分。另外,在这行代码中,当在C中将事件处理程序赋值给OnSwitcherDisconnected时,它使用=+new的SwitcherEventHandle,这是我的TSwitcherEventHandle,但这不是一个对象,我无法创建它的实例。这是我不理解的,我也不知道如何在Delphi中编写这个调用。Invoke在主线程上运行代码。在Delphi中,它是TThread.Synchronize。这还没有完成更多正在进行的工作,但如果我理解清楚,调用将如下所示:m_switcherMonitor.OnSwitcherDisconnected:=TThread.SynchronizeTSwitcherEventHandler;Myabe这种混乱仅仅是由疑问句中使用的词语引起的。您演示的是如何为事件分配处理程序。事件只不过是具有非常特定数据类型的属性:过程类型。与任何其他属性一样,您可以将值分配给事件。这个值也必须是过程类型,这意味着这里是指向类方法的指针。这就是您正确使用运算符的原因:=。Delphi不支持像C这样的多播事件,所以某个事件只能触发一个处理程序。这就是为什么您分配了一个处理程序而没有添加处理程序的原因。@AlexSC,这是一个非常有用的解释。