windowsdelphidrag-and-dropfiremonkeydelphi-12-athens

IFMXDragDropService unexpected gradient effect when DragImage.Height > 300


I have a solitaire game where I'm using IFMXDragDropService to drag a run of cards from one stack to another. I would prefer a drag image that's not semi-transparent (this VCL solution doesn't work in FMX) but other than that it does what I want until the card run is long enough that the drag image height is >300. From that point the drag image transparency has an x-axis gradient effect to it.

The effect can be seen using a form with 2 TImage controls, one with height <=300 and the other >300. (Width >300 will also produce the x-axis effect.) Load PNGs of matching sizes into each of the TImage.Bitmap properties in the form's Create event. Assign the following code to the OnMouseDown event of each TImage:

procedure TFormFMXDrag.ImgMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState;
  X, Y: Single);
var
  Svc: IFMXDragDropService;
  DragData: TDragObject;
  DragImage: TBitmap;
begin
  if TPlatformServices.Current.SupportsPlatformService(IFMXDragDropService, Svc) then
  begin
    DragImage := TBitmap.Create;
    try
      DragImage.Assign(TImage(Sender).Bitmap);
      DragData.Source := Sender;
      Svc.BeginDragDrop(FormFMXDrag, DragData, DragImage);
    finally
      DragImage.Free;
    end;
  end;
end;

DragImage.Height 300 DragImage.Height 301

The means of creating the image doesn't make a difference. I've tried MakeScreenShot, PaintTo and loading the PNGs into the MultiResBitmap property at design time. Where the vertical line of greatest opacity falls is not consistent. It changes each time you start dragging.

Where am I going wrong? I fear the solution will mean implementing my own drag-drop service... which I've never done. I did this in FMX so I wouldn't have to start all over if I decided to target other platforms but at this point the only plan is Windows.


Solution

  • The observed "gradient effect" is not created or managed by the Delphi FMX framework. Its something managed by the Windows OS as the IFMXDragDropService delegates the creation of the drag object to Windows APIs.

    Much like you others have found this "magic" value of 300 pixels by mere testing as there isn't official Windows documentation available for this behavior. As no workaround has been found so far, implementing a custom drag & drop feature suited for your needs, or search for third-party solutions that already solved this problem, is the best course of action here.