Newsgroup: it.comp.lang.delphi
Titolo: Richiamo eventi

Salve,
run-time creo oggetti a cui associo degli eventi, come faccio dopo aver
individuato l'oggetto:
mio_oggetto:=TShape(Form1.FindComponent('Shape'+ID_attuale));
ad eseguire l'evento a lui associato.
N.B. non posso chiamare direttamente l'evento perche' mi serve la posizione
dell'oggetto.
Il progetto e':
creo degli Shape e li muovo  [OK]
in un secondo tempo devo ripercorrere gli stessi movimenti,
quindi quando li muovo la prima volta salvo una lista di [ID_shape,x,y] che
devo passare all'evento onmousemove dello shape.
GRAZIE 1000
faf...@tiscalinet.it

 mio_oggetto:=TShape(Form1.FindComponent('Shape'+ID_attuale));
molto meglio:
var AComponent:TCOmponent;
AComponent := Form1.FindComponent('Shape'+ID_attuale);
if (AComponent is TShape) then 
  mio_oggetto := TShape(AComponent);
Un evento viene chiamato dal componente. Richiamarlo da fuori il
componente non e' altro che chiamare un emtodo della Form su cui sta il
componente.
-- 
I'am what I'am, I do what I can

 ad eseguire l'evento a lui associato.
dipende da che evento vuoi scatenare. Come esempio banale guarda questa 
form
type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    FCnt: Integer;
    procedure Boh;
  public
    { Public declarations }
  end;
var
  Form1: TForm1;
implementation
{$APPTYPE CONSOLE}
{$R *.dfm}
procedure TForm1.Boh;
begin
  Button1.Click;
  Button1Click(nil {o Form1, o Application, o qualcos'altro});
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
  Inc(FCnt);
  Writeln(Format('Button 1 pressed %u times', [FCnt]));
end;
-- 
Mauro Falzari 
   [ 
http://digilander.libero.it/mauro.falzari
 ]
 
 "Se guardi nell'abisso, anche l'abisso guarda in te." 
   (Friedrich Nietzsche)

Usando
procedure TForm1.SpeedButton_eseguisequenzaClick(Sender: TObject);
...
mio_oggetto:=TShape(Form1.FindComponent('Shape'+IntToStr(ID_attuale)));
      mio_oggetto.OnMouseDown(Sender,mbLeft,[ssLeft],x,y);
all'interno di OnMouseDown il Sender č SpeedButton, ma ha me serve che sia
TShape di mio_oggetto come faccio
GRAZIE 1000
faf...@tiscalinet.it

chiedo scusa, ma a causa della fretta mi sono reso conto di aver scritto 
un esempio totalmente privo di senso. 
Questo dovrebbe essere migliore, anche se forse un po' troppo complesso.
Abbiamo una classe TExample in cui ho definito una proprietą Value con un 
evento collegato OnChangeValue che si verifica ogni qualvolta Value viene 
modificata. 
C'č anche un evento OnChangeAborted che si verifica nel caso in cui venga 
richiesto l'annullamento del cambiamento.
Per poter usare questi eventi, siccome ho definito tutto in un singolo 
file DPR (quindi senza la classica Form1), bisogna assegnarli a dei METODI 
DI UN OGGETTO (vedi help "Event types are method-pointer types"). E' per 
questo che ho dovuto aggiungere anche la classe TDummy
////////////////////////////////////////////////////////////////////////
{$APPTYPE CONSOLE}
program Project1;
uses Windows, SysUtils, Classes;
{ Procedura generica }
procedure WriteFmt(const s: string; Args: array of const);
begin
  Writeln(Format(s, Args))
end;
type
  TChangeValueEvent =
    procedure(const OldValue, NewValue: Integer; var Cancel: Boolean) of 
object; {vedi help "Procedural types" }
{ TExample }
  TExample = class
  private
    FValue: Integer;
    FOnChangeValue: TChangeValueEvent;
    FOnChangeAborted: TNotifyEvent;
    procedure DoChangeValue(const OldValue, NewValue: Integer);
    procedure SetValue(const Value: Integer);
  public
    procedure WriteValue;
    property Value: Integer read FValue write SetValue;
    property OnChangeValue: TChangeValueEvent read FOnChangeValue write 
FOnChangeValue;
    property OnChangeAborted: TNotifyEvent read FOnChangeAborted write 
FOnChangeAborted;
  end;
procedure TExample.DoChangeValue(const OldValue, NewValue: Integer);
begin
  WriteFmt('%s.Value sta per essere cambiato da %u a %u', [ClassName, 
OldValue, NewValue]);
end;
procedure TExample.SetValue(const Value: Integer);
var
  bCancel: Boolean;
begin
  bCancel:= False;
  if Value <> FValue then
  begin
    if Assigned(FOnChangeValue) then
      FOnChangeValue(FValue, Value, bCancel);
    if bCancel then
      if Assigned(FOnChangeAborted) then
        FOnChangeAborted(Self)
      else
    else
      begin
        DoChangeValue(FValue, Value);
        FValue:= Value;
      end
  end
end;
procedure TExample.WriteValue;
begin
  WriteFmt('%s.Value = %u', [ClassName, Value]);
end;
type
  TDummy = class
  public
    procedure ConfirmChange(const Old, New: Integer; var Cancel: Boolean);
    procedure ChangeAborted(o: TObject);
  end;
{ TDummy }
procedure TDummy.ChangeAborted(o: TObject);
begin
  WriteFmt('Nessun cambiamento apportato alla proprieta'' %s.Value', 
[o.ClassName] );
end;
procedure TDummy.ConfirmChange(const Old, New: Integer;
  var Cancel: Boolean);
begin
  WriteFmt('Modificare il valore da %u a %u?', [Old, New]);
  Cancel:=
    MessageBox(
      0,
      PChar(Format('Modificare il valore da %u a %u?', [Old, New])),
      PChar('Evento OnChangeValue'),
      MB_YESNO + MB_ICONQUESTION + MB_DEFBUTTON2
    ) = IDNO;
end;
var
  Example: TExample;
  Dummy: TDummy;
  cveStore: TChangeValueEvent;
begin
  Dummy:= TDummy.Create;
  try
    Example:= TExample.Create;
    with Example do
    try
  { assegnamo subito l'evento che si verifica nel caso di annullamento }
      OnChangeAborted:= Dummy.ChangeAborted;
  { qui l'evento OnChangeValue NON si verifica }
      WriteValue;
      Value:= 10;
      WriteValue;
      OnChangeValue:= Dummy.ConfirmChange;
  { adesso sģ }
      Value:= 100;
      WriteValue;
  { memorizziamo l'evento OnChangeValue e mettiamolo momentaneamente a 
tacere }
      cveStore:= OnChangeValue;
      OnChangeValue:= nil;
      Value:= 666;
      WriteValue;
  { ripristiniamo l'evento OnChangeValue }
      OnChangeValue:= cveStore;
      Value:= 123456789;
      WriteValue;
  { richiamiamo l'evento OnChangeAborted, anche se in questo modo non ha 
alcun senso }
      Write('Questo non ha alcun senso: ');
      OnChangeAborted(Dummy);
      Writeln;
      Writeln('Press <Enter> to exit');
      Readln;
    finally
      Free;
    end;
  finally
    Dummy.Free
  end
end.


Il giorno 2 dicembre 2003, fafino ha scritto:
procedure TForm1.SpeedButton_eseguisequenzaClick(Sender: TObject);
var
  mio_oggetto: TShape;
begin
{...}
  mio_oggetto:= TShape(Form1.FindComponent('Shape'+IntToStr(ID_attuale)));
  mio_oggetto.OnMouseDown(mio_oggetto, mbLeft,[ssLeft],x,y);
{...}
end;


 ad eseguire l'evento a lui associato.
La domanda cosi' com'e' non ha molto senso: se ad un evento di un
componente associ un metodo questo viene eseguito quando l'evento
accade.
[Alcuni eventi sono attivati da messagi Win, altri da messaggi Delphi
(CM_XXX), altri da eventi del sistema (TEvent)... Spesso nei componenti
TCustomXxxxx c'e' un metodo DoNomeEvento che non fa altro che chiamare
il gestore dell'evento.]
Se vuoi eseguire il metodo indipendentemente dal verificarsi dell'evento
invochi il metodo passandogli parametri adeguati (vedi sotto)
// creazione del componente
procedure TForm1.btnCreaCompClick(Sender: TObxect)
var aShp: TShape;
begin
  aShp := TShape.Create(Self); inc(fNumShapes);
  aShp.Name := 'Shape' + inttostr(fNumShapes);
  aShp.OnMouseMove := GestioneMouseMove;
  aShp.Parent := Self;    // Form1
  aShp.Tag := fNumShapes;
  ListaShapes.AddObject(aShp.Name, aShp);
end;
type
  TEventoMouse = record
    Shift: TShiftState;
    P: TPoint;
  end;
// Handler di OnMouseMove
procedure TForm1.GestioneMouseMove(Sender: TObject; Shift: TShiftState;
X,
  Y: Integer);
begin
  if Sender is TShape then
    // whatever: store a new TEventoMouse in fListaPunti
  else
    raise EBirichino.Create('Non sei una sagoma');
end;
// _Chiamata di OnMouseMove_ da un Timer
procedure TForm1.Timer1OnTimer(Sender: TObxect)
var aPt: TEventoMouse;
begin
  // supponendo che fTheShapeToShake sia il componente
  // di cui richiamare gli eventi
  inc(fLastPoint);
  if (fListaPunti.Count >= fLastPoint) then begin
    aPt := TEventoMouse(fListaPunti[fLastPoint]);
    fTheShapeToShake.OnMouseMove(fTheShapeToShake, aPt.Shift, aPt.P.X,
aPt.P.Y);
    // o semplicemente
    // GestioneMouseMove(fTheShapeToShake, aPt.Shift, aPt.P.X, aPt.P.Y);
  end;
end;
Saluti
Paolo Arosio
-- 
"La dimostrazione dell'esistenza di specie intelligenti nell'universo
 e' che non ci vengono a trovare"