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

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?
Grazie anticipate per le vostre risposte.

 Grazie anticipate per le vostre risposte.
Ora credo d'aver capito cosa intendi dire. Devi in sostanza subclassare la 
Timage, leggiti l'help relativo alla proprieta' WindowProc.
TMyCtrl
    Image1: TImage;
public
    Old_Proc: TWndMethod;
    procedure NewWinProc(var Mess: TMessage);
....
Constructor TMyCtrl.Create(Sender: TObject);
begin
Inherited Create(AOvner);
Old_Proc:=Image1.WindowProc;
Image1.WindowProc:=NewWindowProc;
end;
Destructor TMyCtrl.Destroy(Sender: TObject);
begin
Image1.WindowProc:=Old_Proc;
Inherited Destroy;
end;
// Attualmente questa e' a tutti gli effetti la WndProc della TImage, cioe' 
qui arrivano tutti i Msg inviati alla TImage
procedure TMyCtrl.NewWinProc(var Mess: TMessage);
begin
// Catturi i messagi di mouse che arrivano alla TImage e li gestici a 
piacere per operazioni su TMyCtrl
if Mess.Msg=WM_LBUTTONUP then
    // Tuo codice
Old_Proc(Mess);
end;
Ciao Giorgio

Giorgio Padoan ha scritto:

Ho provato il codice da te segnalato ma purtroppo non ci siamo ancora.
Quello che succede quando si fa click sull'Image è l'esecuzione del codice
procedure TMyCtrl.NewWinProc(...) // in Unit2
e fin qui tutto ok, ma io vorrei che prima l'evento fosse catturato da
procedure TForm1.MyCtrl_MouseDown(...) // in Unit1
e dopo da
procedure TMyCtrl.NewWinProc(...) // in Unit2
Posto di seguito il codice da me usato.
--------------------------------------------------------------------------------
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;
     i: Integer;
     procedure MyCtrl_MouseDown(Sender: TObject; Button: TMouseButton; 
Shift: TShiftState; X, Y: Integer);
   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.OnMouseDown := MyCtrl_MouseDown;
end;
procedure TForm1.MyCtrl_MouseDown(Sender: TObject; Button: TMouseButton; 
Shift: TShiftState; X, Y: Integer);
begin
   i := 3;
end;
end.
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;
     destructor Destroy(Sender: TObject);
   public
     a: Integer;
     Old_Proc: TWndMethod;
     procedure NewWinProc(var Mess: TMessage);
   published
    property OnMouseDown;
   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('...');
   Old_Proc := Image.WindowProc;
   Image.WindowProc := NewWinProc;
end;
destructor TMyCtrl.Destroy(Sender: TObject);
begin
   Image.WindowProc := Old_Proc;
   Inherited Destroy;
end;
procedure TMyCtrl.NewWinProc(var mess: TMessage);
begin
   // Catturi i messagi di mouse che arrivano alla TImage e li gestici a 
piacere per operazioni su TMyCtrl
   if mess.Msg = WM_LBUTTONDOWN then begin
     a := 1;
   end;
   Old_Proc(mess);
end;
end.

> end;
Il Click non essendo diretto al TMyCtrl non verra' mai catturato dal questo 
componente.
Le righe che ti ho inviato permettono di catturarlo a livello della TImage 
prima che questa lo gestisca.
Se vuoi che produca un click anche nella TMyCtrl dovrebbe bastare un:
if Mess.Msg=WM_LBUTTONUP then
    Click;
Giorgio