德尔福事件处理,如何创建自己的事件

问题描述:

我是新来的Delphi开发。我必须创建一个事件并传递一些属性作为参数。有人可以分享一些演示程序,展示如何从头开始。我几乎在每个网站上搜索了一下,他们都给了一段代码,但我需要的是一个简单易懂的完整的程序。德尔福事件处理,如何创建自己的事件

+4

请解释一下你实际上是试图做的,所以提供足够的信息我们可以建议替代路线;因为我怀疑你问的实际问题的答案不会帮助你。 >新建 - - > VCL窗体应用程序文件: – 2011-04-26 06:29:54

+0

''要使用事件做得到完全的程序。你有它,这是一个完整的工作示例,说明如何使用事件,完整的源代码.''。但正如我在之前的评论中提到的,我怀疑这就是你实际需要的。一般来说很难从完整的课程中学习。 – 2011-04-26 06:34:16

+0

谢谢,我其实是一个想在delphi中精心创建事件的小程序。我如何在delphi中创建自己的事件。 – mac 2011-04-26 06:37:03

您可以使用一个事件处理反应过来的时候什么事情发生(例如AfterCreation之前关闭)。

为了使用事件自己的类,您需要定义事件类型。更改所需参数的类型和数量。

type 
    TMyProcEvent = procedure(const AIdent: string; const AValue: Integer) of object; 
    TMyFuncEvent = function(const ANumber: Integer): Integer of object; 

在该类中,您可以添加一个DoEvent(为适当的事件重命名)。所以你可以在内部调用DoEvent。 DoEvent处理未分配事件的可能性。

type 
    TMyClass = class 
    private 
    FMyProcEvent : TMyProcEvent; 
    FMyFuncEvent : TMyFuncEvent; 
    protected 
    procedure DoMyProcEvent(const AIdent: string; const AValue: Integer); 
    function DoMyFuncEvent(const ANumber: Integer): Integer; 

    public 
    property MyProcEvent: TMyProcEvent read FMyProcEvent write FMyProcEvent; 
    property MyFuncEvent: TMyFuncEvent read FMyFuncEvent write FMyFuncEvent; 
    end; 

procedure TMyClass.DoMyProcEvent(const AIdent: string; const AValue: Integer); 
begin 
    if Assigned(FMyProcEvent) then 
    FMyProcEvent(AIdent, AValue); 
    // Possibly add more general or default code. 
end; 


function TMyClass.DoMyFuncEvent(const ANumber: Integer): Integer; 
begin 
    if Assigned(FMyFuncEvent) then 
    Result := FMyFuncEvent(ANumber) 
    else 
    Result := cNotAssignedValue; 
end; 
+0

参数被OP特别要求... – 2011-04-26 07:04:20

+0

谢谢亲爱的,非常有帮助。但仍不能复制粘贴,然后只需更改属性即可实现不同的结果。 – mac 2011-04-26 07:13:44

+12

@mac,如果代码对你来说不是复制粘贴友好的,就让它自己复制粘贴友好。如果您对代码不了解,请要求澄清。只是要求更多的复制粘贴友好代码,让你看起来像一个懒惰的[你是否haz德代码](http://meta.serverfault.com/questions/1039/what-is-do-you-haz-teh-codez )类型。 – 2011-04-26 07:43:53

下面是一个简短但很完整的控制台应用程序,演示如何创建在Delphi自己的事件。包括从类型声明到调用事件的所有内容。阅读代码中的注释以了解发生了什么。

program Project23; 

{$APPTYPE CONSOLE} 

uses 
    SysUtils; 

type 
    // Declare an event type. It looks allot like a normal method declaration except 
    // it suffixed by "of object". That "of object" tells Delphi the variable of this 
    // type needs to be assigned a method of an object, not just any global function 
    // with the correct signature. 
    TMyEventTakingAStringParameter = procedure(const aStrParam:string) of object; 

    // A class that uses the actual event 
    TMyDummyLoggingClass = class 
    public 
    OnLogMsg: TMyEventTakingAStringParameter; // This will hold the "closure", a pointer to 
               // the method function itself + a pointer to the 
               // object instance it's supposed to work on. 
    procedure LogMsg(const msg:string); 
    end; 

    // A class that provides the required string method to be used as a parameter 
    TMyClassImplementingTheStringMethod = class 
    public 
    procedure WriteLine(const Something:string); // Intentionally using different names for 
               // method and params; Names don't matter, only the 
               // signature matters. 
    end; 

    procedure TMyDummyLoggingClass.LogMsg(const msg: string); 
    begin 
    if Assigned(OnLogMsg) then // tests if the event is assigned 
     OnLogMsg(msg); // calls the event. 
    end; 

    procedure TMyClassImplementingTheStringMethod.WriteLine(const Something: string); 
    begin 
    // Simple implementation, writing the string to console 
    Writeln(Something); 
    end; 

var Logging: TMyDummyLoggingClass; // This has the OnLogMsg variable 
    LoggingProvider: TMyClassImplementingTheStringMethod; // This provides the method we'll assign to OnLogMsg 

begin 
    try 
    Logging := TMyDummyLoggingClass.Create; 
    try 

     // This does nothing, because there's no OnLogMsg assigned. 
     Logging.LogMsg('Test 1'); 

     LoggingProvider := TMyClassImplementingTheStringMethod.Create; 
     try 
     Logging.OnLogMsg := LoggingProvider.WriteLine; // Assign the event 
     try 

      // This will indirectly call LoggingProvider.WriteLine, because that's what's 
      // assigned to Logging.OnLogMsg 
      Logging.LogMsg('Test 2'); 

     finally Logging.OnLogMsg := nil; // Since the assigned event includes a pointer to both 
             // the method itself and to the instance of LoggingProvider, 
             // need to make sure the event doesn't out-live the LoggingProvider            
     end; 
     finally LoggingProvider.Free; 
     end; 
    finally Logging.Free; 
    end; 
    except 
    on E: Exception do 
     Writeln(E.ClassName, ': ', E.Message); 
    end; 
end. 
+0

非常感谢,很好的例子,你是否也提供了基于表单的示例,因为它是基于控制台的。我需要在表单上创建我自己的事件并获得一些东西。谢谢你的好例子。 – mac 2011-04-26 07:20:29

+22

@mac不,我不能。这*是一个完整的例子,在表单上做同样的事情并不需要*任何特殊的*;表单只是像其他任何类一样的类。做一个基于表单的例子需要至少3个文件(dpr,dfm + pas),并且不添加任何*新的。我仍然怀疑这不是你所需要的,但是因为你不想回答“为什么”这个问题,所以我不能做得更好。 – 2011-04-26 07:29:31

完整的项目回答是好。但是,这是一个备选答案,以您已经拥有的形式展示如何去做你想做的事。

进入您的形式,并转到接口部分,在二类地区,表单的类定义之外,并添加一个类型:

interface 
type 
    TMyEvent = procedure(Sender:TObject;Param1,Param2,Param3:Integer) of object; 

    TMyForm = class(TForm) 
      .... 

这是传统的,但不是必需的,第一项在你的事件中是发送它的对象,但要使用基类TObject而不是表单的实际类类型。
上面的其他参数完全不需要,但显示你将如何声明自己的附加数据。如果你不需要它们,那么只需使用发件人:TObject。 在这种情况下,您不必定义TMyEvent,只需使用TNotifyEvent类型即可。

现在宣布使用该类型,在你的表单字段:

TMyForm = class(TForm) 
private 
    FMyEvent : TMyEvent; 
    ... 

现在宣布访问该字段,在窗体的属性部分属性:

// this goes inside the class definition just before the final closing end 
property MyEvent:TMyEvent read FMyEvent write FMyEvent 

现在去哪里你想要那个事件“火”(如果设置被调用),并写:

// this goes inside a procedure or function, where you need to "fire" the event. 
procedure TMyForm.DoSomething; 
begin 
    ... 
    if Assigned(FMyEvent) then FMyEvent(Self,Param1,Param2,Param3); 
end; 
+0

谢谢沃伦;我会尝试用delphi做一些事情,实际上问题是,程序流程,或者我需要在一个单元中定义和调用事件,或者需要另一个单元来定义事件和分配属性,然后调用此事件一个按钮点击事件。像进度条和百分比计数器一样。 – mac 2011-04-27 05:49:57

+2

我不知道你的意思。如果你问一个不同的问题,最好还是不清楚。 – 2012-10-23 20:56:08

在将“事件”成DLL的方面,我描述了使用界面的概念,一步一步...也许这有助于以不同的方式:Using event listeners in a non-gui environment (DLL) (Delphi)

+0

这将是一个很好的评论。 – 2014-11-13 07:27:39