德尔福事件处理,如何创建自己的事件
我是新来的Delphi开发。我必须创建一个事件并传递一些属性作为参数。有人可以分享一些演示程序,展示如何从头开始。我几乎在每个网站上搜索了一下,他们都给了一段代码,但我需要的是一个简单易懂的完整的程序。德尔福事件处理,如何创建自己的事件
您可以使用一个事件处理反应过来的时候什么事情发生(例如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;
参数被OP特别要求... – 2011-04-26 07:04:20
谢谢亲爱的,非常有帮助。但仍不能复制粘贴,然后只需更改属性即可实现不同的结果。 – mac 2011-04-26 07:13:44
@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.
非常感谢,很好的例子,你是否也提供了基于表单的示例,因为它是基于控制台的。我需要在表单上创建我自己的事件并获得一些东西。谢谢你的好例子。 – mac 2011-04-26 07:20:29
@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;
谢谢沃伦;我会尝试用delphi做一些事情,实际上问题是,程序流程,或者我需要在一个单元中定义和调用事件,或者需要另一个单元来定义事件和分配属性,然后调用此事件一个按钮点击事件。像进度条和百分比计数器一样。 – mac 2011-04-27 05:49:57
我不知道你的意思。如果你问一个不同的问题,最好还是不清楚。 – 2012-10-23 20:56:08
在将“事件”成DLL的方面,我描述了使用界面的概念,一步一步...也许这有助于以不同的方式:Using event listeners in a non-gui environment (DLL) (Delphi)
这将是一个很好的评论。 – 2014-11-13 07:27:39
请解释一下你实际上是试图做的,所以提供足够的信息我们可以建议替代路线;因为我怀疑你问的实际问题的答案不会帮助你。 >新建 - - > VCL窗体应用程序文件: – 2011-04-26 06:29:54
''要使用事件做得到完全的程序。你有它,这是一个完整的工作示例,说明如何使用事件,完整的源代码.' '。但正如我在之前的评论中提到的,我怀疑这就是你实际需要的。一般来说很难从完整的课程中学习。 –
2011-04-26 06:34:16
谢谢,我其实是一个想在delphi中精心创建事件的小程序。我如何在delphi中创建自己的事件。 – mac 2011-04-26 06:37:03