2011-04-26 42 views
15

Soy nuevo en el desarrollo de delphi. Tengo que crear un evento y pasar algunas propiedades como parámetros. ¿Podría alguien compartir algún programa de demostración que muestre cómo hacerlo desde cero? Busqué en Google casi todos los sitios, todos dieron un código, pero lo que necesito es un programa completo que sea simple y comprensible.Manejo de eventos Delphi, cómo crear un evento propio

+4

Por favor explique lo que está tratando de hacer, proporcionando suficiente información para podemos sugerir rutas alternativas; Porque sospecho que una respuesta a la pregunta real que hizo no lo ayudará. –

+0

'' Para obtener un programa completo usando eventos, haga: Archivo -> Nuevo -> Solicitud de formularios VCL. Ahí lo tiene, es un ejemplo de trabajo completo de cómo usar eventos, con fuente completa. '. Pero como mencioné en mi comentario anterior, dudo que sea eso lo que realmente necesita. En general, es difícil aprender de programas completos. –

+0

Gracias, de hecho quiero un pequeño programa en el que se elabore la creación de eventos en Delphi. ¿Cómo puedo crear mis propios eventos en Delphi? – mac

Respuesta

12

Utiliza un controlador de eventos para reaccionar cuando sucede algo más (por ejemplo, AfterCreation y antes del cierre).

Para utilizar eventos para su propia clase, debe definir el tipo de evento. Cambia el tipo y la cantidad de parámetros necesarios.

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

En la clase, puede agregar un DoEvent (cambiar el nombre para el evento apropiado). ASÍ PUEDES llamar al DoEvent internamente. DoEvent maneja la posibilidad de que un evento no esté asignado.

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

Los parámetros fueron específicamente solicitados por el OP ... –

+0

Gracias querida, muy útil. pero aún no es para copiar, pegar y luego simplemente cambiar la propiedad puede lograr resultados diferentes. – mac

+12

@mac, si el código no es compatible con copiar y pegar, hágala usted mismo copiar y pegar. Si no entiende un poco del código, solicite aclaraciones. Simplemente pedir más código compatible con copiar y pegar te hace ver como un vago [Haz clic aquí] (http://meta.serverfault.com/questions/1039/what-is-do-you-haz-teh-codez) tipo. –

44

Aquí hay una aplicación de consola breve pero completa que muestra cómo crear su propio evento en Delphi. Incluye todo, desde declaración de tipo hasta llamar al evento. Lee los comentarios en el código para entender lo que está pasando.

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

Muchas gracias, Buen ejemplo, ¿también proporciona un ejemplo basado en formulario, ya que está basado en la consola. Necesito crear mis propios eventos en forma y obtener algo como out put. Gracias por amable ejemplo. – mac

+22

@mac no, no puedo. Este * es * un ejemplo completo, hacer lo mismo en un formulario no requiere * nada especial *; Un formulario es solo una clase como cualquier otra clase. Hacer un ejemplo basado en formularios requiere un mínimo de 3 archivos (dpr, dfm + pas) y no agrega * nada * nuevo. Todavía sospecho que esto no es lo que necesitas, pero como no quieres responder la pregunta de "para qué", no puedo hacer nada mejor. –

17

La respuesta del proyecto completo es buena. Pero esta es una respuesta alternativa que muestra cómo hacer lo que quiere, en una forma que ya tiene.

entrar en su forma, y ​​vaya a la sección de interfaz, en el área de tipos, fuera de la definición de clase de su forma y añadir un tipo:

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

    TMyForm = class(TForm) 
      .... 

Es tradicional, pero no se requiere, que el primer elemento en su caso, sea el objeto que lo envíe, pero use TObject de clase base en lugar del tipo de clase real de su formulario.
Los demás parámetros anteriores no son necesarios en absoluto, pero le muestran cómo declararía sus propios datos adicionales. si no los necesita, simplemente use Sender: TObject. Y en ese caso, no tiene que definir TMyEvent en absoluto, solo use el tipo TNotifyEvent.

Ahora declarar un campo que utiliza ese tipo, en su forma:

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

Ahora declarar una propiedad que tiene acceso a ese campo, en la sección de propiedades del formulario:

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

Ahora ve a donde desea que ese evento 'prenda' (se le llame si está configurado) y escriba esto:

// 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

Gracias Warren; Trataré de hacer algo con Delphi, en realidad el problema es el flujo del programa, ya sea que necesite definir y llamar el evento en una sola unidad o le tome a otra unidad definir las propiedades de Evento y Asignar y luego llamar a este evento con un evento de clic de botón. Como barra de progreso y contador de porcentaje. – mac

+2

No tengo idea de lo que quieres decir. Es mejor si hace una pregunta diferente, si todavía no está claro. –

Cuestiones relacionadas