Newsgroup: it.comp.lang.delphi
Titolo: Intercettare eventi di un controllo composto

Ho un controllo composto TMyCtrl discendente da TCustomControl che 
contiene a sua volta un controllo TImage (vedi Unit2).
Devo intercettare l'evento click prima su MyCtrl (e qui eseguire alcune 
operazioni) e dopo su Image (e qui eseguire altre operazioni).
Invece quello che ottengo è solamente l'evento click su Image. Sembra 
che MyCtrl non catturi l'evento dato che stato catturato prima da Image.
Dove sto sbagliando?
Segue il codice sorgente:
----------------------------------------------------------------------Unit1.pas
unit Unit1;
interface
uses
   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, 
Forms,
   Dialogs, ExtCtrls, Unit2;
type
   TForm1 = class(TForm)
     procedure FormCreate(Sender: TObject);
   private
     { Private declarations }
   public
     { Public declarations }
     MyCtrl: TMyCtrl;
     procedure MyCtrl_Click(Sender: TObject);
   end;
var
   Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
   MyCtrl := TMyCtrl.Create(Self);
   MyCtrl.Parent := Self;
   MyCtrl.Top := 0;
   MyCtrl.Left := 0;
   MyCtrl.Align := alClient;
   MyCtrl.OnClick := MyCtrl_Click;
end;
procedure TForm1.MyCtrl_Click(Sender: TObject);
begin
   // operazioni da effetuare quando l'utente fa click sul controllo MyCtrl
end;
end.
----------------------------------------------------------------------Unit2.pas
unit Unit2;
interface
uses
   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, 
Forms,
   Dialogs, ExtCtrls;
type
   TMyCtrl = class(TCustomControl)
     Image: TImage;
     constructor Create(AOwner: TComponent); override;
   private
     FImageOnClick: TNotifyEvent;
     procedure OnImageClick(Sender : TObject);
   public
   published
     property ImageClick: TNotifyEvent read FImageOnClick write 
FImageOnClick;
     property OnClick;
   end;
implementation
constructor TMyCtrl.Create(AOwner: TComponent);
begin
   inherited Create(AOwner);
   ControlStyle := ControlStyle + [csAcceptsControls, csClickEvents];
   Image := TImage.Create(Self);
   Image.Parent := Self;
   Image.Left := 0;
   Image.Top := 0;
   Image.Stretch := True;
   Image.AutoSize := True;
   Image.Picture.LoadFromFile('photo.bmp');
   Image.OnClick := OnImageClick;
end;
procedure TMyCtrl.OnImageClick(Sender: TObject);
begin
   if assigned(FImageOnClick) then FImageOnClick(Self);
end;
end.



Per intercettare il click su TMyCtrl, dovresti fare l'override del
metodo click di TControl all'interno della definizione di TMyCtrl. Se
il click è effettuato anche nell'area dell'immagine allora invochi
anche fImageOnClick.In questo caso il metodo OnImageClick di TMyCtrl
serve solamente a te per verificare che il click sia stato effettuato
sopra Image.


 Dove sto sbagliando?
Se il mouse e' sopra la TImage, e' giusto che sia cosi'.
Al momento mi vengono in mente 2 cose:
- catturi l'evento tramite la WndProc della TImage
procedure TImagel.WndProc(var Message: TMessage);
begin
 { Catturi l'evento click e inserisci il tuo codice}
 inherited WndProc(Message);
end;
- catturi l'evento tramite la Application.OnMesssage 

> Al momento mi vengono in mente 2 cose:
Ne aggiungo una io:
Dichiari una classe derivata da TControl:
type
  TFakeControl = Class(TControl)
  end;
e nell'OnClick dell'immagine scrivi:
....
....
     TFakeControl(AParentControl).Click;
....
....
La classe TControl ha un metodo *protected* chiamato Click; che esegue
l'eventuale codice legato all'evento OnClick del controllo stesso.
Essendo questa *protected* non hai accesso diretto se non tramite
classe derivata.
Acqua

     TFakeControl(AParentControl).Click;
Mi sembrava stesse creando un nuovo componente, ho cosi' escluso la 
possibilita' di usare l'onclick dell'immagine, Giorgio 

Ripropongo nuovamente il mio dilemma.
Ho un componente composto come il seguente:
type
   TMyCtrl = class(TCustomControl)
     Image: TImage;
     ...
   end;
var
   MyCtrl: TMyCtrl;
Dove l''area client dell'oggetto Image coprirà interamente l'area client 
dell'oggetto MyCtrl.
Ho bisogno di intercettare gli eventi standard del mouse (e.g. OnClick, 
OnMouseDown, ecc.)
prima dall'oggetto possessore MyCtrl (e qui eseguire alcune operazioni)
e dopo dall'oggetto posseduto Image (e qui eseguire altre operazioni).
Prima domanda, questo è fattibile?

 Ripropongo nuovamente il mio dilemma.
Ti ripropongo la risposta già data!
Dichiari una classe derivata da TControl:
type
  TFakeControl = Class(TControl)
  end;
e nell'OnClick dell'immagine scrivi:
....
....
     TFakeControl(Parent).Click;
     <tuo codice>
....
....
spero tu abbia capito come usare questo codice. Purtroppo non ho tempo per 
entrare nei dettagli. Finalmente si parte per un pò di riposo.
Colgo l'occasione per salutare tutto il NG (Morde, Salvati, Breveglieri, 
Jax, Mao SW, ma si... anche Laforgia ;) ti voglio bene, tutta la comitiva 
della famosissima "cena dello stinco" e tutto coloro che in questo momento 
non mi vengono in mente ma vado veramente di fretta) ed augurare anche a voi 
buone vacanze!!!!
Non lavorate troppo altrimenti vi rridurrete come me!!!!
Salutoni,
Acqua

 
Purtroppo non ho ben capito il tuo suggerimento, casomai quando torni 
dalle fiere saresti così gentile da descrivermelo meglio?
Grazie e buone ferie!!!

 Colgo l'occasione per salutare tutto il NG
[SNIP]
Toh..! Ogni tanto ci si rivede... :-D
Un caro saluto, fai buone vacanze! 
Ciao!
-- 
Morde