Ceci est une ancienne révision du document !


Drag & Drop

Afficher une image lors d'un Drag & Drop

Pour afficher une image lors d'un drag and drop dans Lazarus, vous pouvez utiliser la méthode décrite ci-dessous. Cette méthode est inspirée des exemples fournis avec Lazarus, situés dans le répertoire `exemples/dragimagelist`.

1. Définir une classe dérivée de `TDragControlObjectEx`

La première étape consiste à créer une classe dérivée de `TDragControlObjectEx` qui encapsulera la logique pour afficher l'image lors du drag and drop.

Déclaration de la classe :

{ TTileDragObject }
 
interface
 
uses
  Classes, Controls, DragDrop, Graphics, ImgList, Windows;
 
type
  TTileDragObject = class(TDragControlObjectEx)
  private
    FDragImages: TDragImageList;
  protected
    function GetDragImages: TDragImageList; override;
  public
    constructor Create(AControl: TControl); override;
    destructor Destroy; override;
  end;

Implémentation de la classe :

implementation
 
{ TTileDragObject }
 
function TTileDragObject.GetDragImages: TDragImageList;
begin
  Result := FDragImages;
end;
 
constructor TTileDragObject.Create(AControl: TControl);
var
  vBitmap: Graphics.TBitmap;
begin
  inherited Create(AControl);
  FDragImages := TDragImageList.Create(AControl);
  AlwaysShowDragImages := True;  // Remplacez par C_SHOW_DRAG_IMAGE si nécessaire
  vBitmap := Graphics.TBitmap.Create;
  try
    vBitmap.Width := AControl.Width;
    vBitmap.Height := AControl.Height;
    if (AControl is TWinControl) and (csReplicatable in AControl.ControlStyle) then //csReplicatable signifie que la methode PaintTo est implementée
      TWinControl(AControl).PaintTo(vBitmap.Canvas, 0, 0);
    FDragImages.Width := vBitmap.Width;
    FDragImages.Height := vBitmap.Height;
    FDragImages.Add(vBitmap, nil);
    FDragImages.DragHotspot := Mouse.CursorPos - AControl.ClientOrigin; // Positionne le DragHotSpot a l'endroit ou a été saisie le Control 
  finally
    vBitmap.Free;
  end;
end;
 
destructor TTileDragObject.Destroy;
begin
  FDragImages.Free;
  inherited Destroy;
end;

2. Implémenter la méthode `PaintTo` dans le contrôle

Le contrôle à partir duquel l'image sera dessinée doit implémenter la méthode PaintTo.

Si la méthode PaintTo fonctionne pour un Control, le Control doit avoir le membre [csReplicatable] dans son ControleStyle, voir csreplicatable

procedure TTICTileControl.Paint;
var
  ARect: TRect;
begin
  ARect := GetClientRect;
  Canvas.FillRect(ARect);
  // Dessinez ici le contenu de votre contrôle
end;
 
{ Si la methode PaintTo est implementée, il est bon de definir ControleStyle+[csReplicatable] }
procedure TTICTileControl.PaintTo(DC: HDC; X, Y: Integer);
var
  DCChanged: Boolean;
begin
  DCChanged := (not Canvas.HandleAllocated) or (Canvas.Handle <> DC);
  if DCChanged then
    Canvas.Handle := DC;
  try
    Paint;
  finally
    if DCChanged then
      Canvas.Handle := 0;
  end;
end;

3. Créer et initialiser le `TDragObject` dans l'événement `OnStartDrag`

Lorsque le drag and drop commence, vous devez créer et initialiser votre TTileDragObject.

procedure TTICTileControl.DoStartDrag(var DragObject: TDragObject);
var
  vDO: TTileDragObject;
begin
  vDO := TTileDragObject.Create(Self);
  vDO.Control := Self;
  DragObject := vDO;
  // Ajoutez ici tout autre initialisation nécessaire
end;

Conclusion

En utilisant cette approche, vous créez un objet de type TTileDragObject qui contient un 'TDragImageList pour gérer l'affichage de l'image lors du drag and drop. L'image est dessinée à partir du contrôle source grâce à la méthode PaintTo''. Cette méthode permet de dessiner le contrôle dans un bitmap, qui est ensuite utilisé pour afficher l'image lors du drag.

Cette méthode est particulièrement utile lorsque vous voulez fournir une visualisation visuelle immédiate et claire de ce qui est en cours de déplacement, ce qui peut améliorer l'expérience utilisateur lors du drag and drop.

Vous pourriez laisser un commentaire si vous étiez connecté.