Bonjour
J'utilise Delphi 2005 Perso.

Je suis en train de me faire un petit composant dérivé d'un Timage.
Je lui ai implementé:

  1. une collection (des pictogramme ameliorés)
  2. la procedure OnMouseLeave/Enter par interception de Cm_MouseLeave/Enter
  3. OnMouseLeave/Enter au niveau des Item de ma collection


Dans la version surchargé de Mon MouseMove je gere le OnMouseEnter/Leave de mon item comme ceci

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
procedure TimageEtape.MouseMove(Shift: TShiftState; X, Y: Integer);
Var
   RectCercle : TRect;
   ZoneMove : TZoneIndex;
   Dx, Dy : Integer;
   RegionLibre : HRGN;
begin
     //detection Move on Etape
     ZoneMove := PointToEtapeIndex(Point(X,Y));
     If ZoneMove.Index <> -1  Then
     Begin
          If FItemEnter.Index = -1 Then
          begin
               FItemEnter := ZoneMove;
               Etapes[ZoneMove.Index].MouseEnter(Self, Shift, X, Y, ZoneMove);
          end;
          Etapes[ZoneMove.Index].MouseMove(Self, Shift, X, Y, ZoneMove);
          If FMode <> M_Modify Then Exit;//On est dans un EtapeItem l'evenement sera gerer par MouseDownItem
     end
     else
     begin
          If FItemEnter.Index <> -1 Then
          begin
               Etapes[FItemEnter.Index].MouseLeave(Self, Shift, X, Y, ZoneMove);
               FItemEnter.Index := -1;
          end;
     end;
[...]
Tout ceci marche bien a condition qu'a la sortie de mon item ma souris retourne sur la surface de mon composant, sinon je n'est pas le OnMouseLeave (de mon item) tant que la souris ne revient pas en contact avec mon composant. Ce qui est logic.

Pour regler le probleme ... du moins je le croyais, j'ai decidé d'utiliser le OnMouseLeave de mon composant et de declencher le onMouseLeave de mon item avec, la souris n'etant plus sur mon composant, elle n'est plus sur l'item non plus de ce faite!

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
procedure TImageEtape.MouseLeave(var Msg: TMessage);
var
   Curs : TMouse;
   CursInCtrl : TPoint;
   Shift : TShiftState;
begin
     If FItemEnter.Index <> -1 then
     begin
          Curs := TMouse.Create;
          CursInCtrl := ScreenToClient(Curs.CursorPos);
          //On omet ici dans la declaration de Shift la position des boutons souris
          Shift := ShiftState;
          Etapes[FItemEnter.Index].OnMouseLeave(Self,Shift,CursInCtrl.X, CursInCtrl.Y,FItemEnter);
          FItemEnter.Index := -1;
     end;
     If Assigned(FOnMouseLeave) Then FOnMouseLeave(Self);
end;
Mais ca ne fonctionne pas
Lorsque je quite la fenetre sans passer par la surface de mon composant, en posant par exemple un Boutton sur le quel je vais avec ma souris, j'ai une erreur EaccessViolation à l'adresse 00000000000. Lecture de L'adresse 000000000 (j'ai pas exactement compté les zeros mais en tout cas y'a pas de chiffre autre)

Voila la declaration de mes variables au niveau de mes Item

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
 TEtape = Class(TCollectionItem)
  private
    FImageEtape : TImageEtape;
[...]
 
    FOnClick : TNotifyEvent;
    FonMouseDown : TMouseButExEvent;
    FonMouseUp : TMouseButExEvent;
    FOnMouseMove : TMouseMoveExEvent;
    FOnMouseLeave : TMouseMoveExEvent;
    FOnMouseEnter : TMouseMoveExEvent;
[...]
 
  protected
    function GetDisplayName : string; override;
 
  public
    constructor Create(Collection : TCollection); override;
    destructor Destroy; override;
 
    procedure Assign(Source : TPersistent); override;
    procedure AssignGroupe(New : TGroupe);
 
    procedure Click;
    procedure MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer; Zone : TZoneIndex);
    procedure MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer; Zone : TZoneIndex);
    procedure MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer; Zone : TZoneIndex);
    procedure MouseEnter(Sender: TObject; Shift: TShiftState; X, Y: Integer; Zone : TZoneIndex);
    procedure MouseLeave(Sender: TObject; Shift: TShiftState; X, Y: Integer; Zone : TZoneIndex);
 
  published
[...]
    property OnClick : TNotifyEvent read FOnClick write FOnClick;
    property OnMouseUp : TMouseButExEvent read  FonMouseUp write FonMouseUp;
    property OnMouseDown : TMouseButExEvent read  FonMouseDown write FonMouseDown;
    property OnMouseMove : TMouseMoveExEvent read  FonMouseMove write FonMouseMove;
    Property OnMouseEnter: TMouseMoveExEvent read FOnMouseEnter write FOnMouseEnter;
    Property OnMouseLeave: TMouseMoveExEvent read FOnMouseLeave write FOnMouseLeave;
 
  end;
Et la au niveau de mon composant

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
  TImageEtape = class(TPaintBox)//(TImage)    ImgCercle.Picture.Graphic
  public
[...]
 
  private
    FEtapes : TEtapes;
[...]
    FOnClickEtape : TEtapeClickEvent;
    FPicture : TPicture;
 
    FMoveEnCours : TZoneIndex;
    FOldMousePos : TPoint;
    FItemEnter : TZoneIndex;
 
    FOnMouseDownItem : TMouseButExEvent;
    FOnMouseUpItem : TMouseButExEvent;
    FOnMouseMoveItem : TMouseMoveExEvent;
    FOnMouseEnterItem : TMouseMoveExEvent;
    FOnMouseLeaveItem : TMouseMoveExEvent;
    FOnMouseEnter : TNotifyEvent;
    FOnMouseLeave : TNotifyEvent;
 
[...]
    function ShiftState: TShiftState;
[...]
  protected
    procedure MouseDown(Button : TMouseButton; Shift : TShiftState; X, Y : integer); override;
    procedure MouseUp(Button : TMouseButton; Shift : TShiftState; X, Y : integer); override;
    procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
 
    procedure MouseDownItem(Sender : TObject; Button : TMouseButton; Shift : TShiftState; X, Y : integer; Zone : TZoneIndex); Virtual;
    procedure MouseUpItem(Sender : TObject; Button : TMouseButton; Shift : TShiftState; X, Y : integer; Zone : TZoneIndex); Virtual;
    procedure MouseMoveItem(Sender : TObject; Shift: TShiftState; X, Y: Integer; Zone : TZoneIndex);Virtual;
 
    procedure DoMouseDownItem(Sender : TObject; Button : TMouseButton; Shift : TShiftState; X, Y : integer; Zone : TZoneIndex);virtual;
    procedure DoMouseUpItem(Sender : TObject; Button : TMouseButton; Shift : TShiftState; X, Y : integer; Zone : TZoneIndex);virtual;
    procedure DoMouseMoveItem(Sender : TObject; Shift: TShiftState; X, Y: Integer; Zone : TZoneIndex);Virtual;
 
    procedure MouseEnterItem(Sender: TObject; Shift: TShiftState; X, Y: Integer; Zone : TZoneIndex);
    procedure MouseLeaveItem(Sender: TObject; Shift: TShiftState; X, Y: Integer; Zone : TZoneIndex);
 
    procedure DoMouseEnterItem(Sender: TObject; Shift: TShiftState; X, Y: Integer; Zone : TZoneIndex);
    procedure DoMouseLeaveItem(Sender: TObject; Shift: TShiftState; X, Y: Integer; Zone : TZoneIndex);
 
    procedure MouseEnter(var Msg: TMessage); message CM_MouseEnter;
    procedure MouseLeave(var Msg: TMessage); message CM_MouseLeave;
 
 [...]
 
    procedure ClickEtape(Index : integer);
    procedure DoClickEtape(Index : integer; Zone : TZoneEtape); virtual;
 
  published
[...]
    property OnClickEtape : TEtapeClickEvent read FOnClickEtape write FOnClickEtape;
    property OnMouseDownItem : TMouseButExEvent read FOnMouseDownItem write FOnMouseDownItem;
    property OnMouseUpItem : TMouseButExEvent read FOnMouseUpItem write FOnMouseUpItem;
    property OnMouseMoveItem : TMouseMoveExEvent read FOnMouseMoveItem write FOnMouseMoveItem;
    property OnMouseEnterItem : TMouseMoveExEvent read FOnMouseEnterItem write FOnMouseEnterItem;
    property OnMouseLeaveItem : TMouseMoveExEvent read FOnMouseLeaveItem write FOnMouseLeaveItem;
    property OnMouseEnter : TNotifyEvent read FOnMouseEnter write FOnMouseEnter;
    property OnMouseLeave : TNotifyEvent read FOnMouseLeave write FOnMouseLeave;
 
    property OnNewItem : TNewItemEvent read FOnNewItem write FOnNewItem;
  end;
Et enfin les Type que j'utilise

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 
Type
    TImageEtape = Class;
 
 
    TZoneEtape = (Ze_Fleche, Ze_FlecheExt, Ze_FlecheOri, Ze_Cercle, Ze_Cadenas, Ze_BtnDel, Ze_BtnHidePicto, Ze_BtnEnEtape, Ze_Out);
    TZoneIndex = Record
         Zone : TZoneEtape;
         Index : Integer;
    End;
 
    TTypePicto = (tp_CercleEtape = 1,tp_CercleVide,tp_CercleCad = 10, tp_CadRedF = 4, tp_CadenasRedO = 5, tp_CadBlackF = 6, tp_CadBlackO = 7);
    TEtatEtape = (Et_Libre  = 10, Et_LibreC = 12, Et_Fleche = 1, Et_Cercle = 2, Et_Cadenas = 3, Et_Complet = 99);
 
    TMode = (M_Actif, M_Free, M_Modify);

Si quelqu'un a une idée ou une piste merci d'avance
A++
Qwaz