Question

The code below enables a control (a label for instance) to show drag images while the dragging operation.

My problem is that I do not want to show the drag image instanly when the dragging begins, I want the image to be displayed when the mouse is on specific boundaries of the control - eg. in the right half of the label .

So far I haven't been able to find a solution for this - the image just gets displayed instantly (unless I modify the VCL source). I appreciate any tricks at this point to get the desired behaviour before abondoning VCL drag&drop utilities and roll a custom one capturing the mouse.

Here's an example pseudocode to enable drag images for a label..

{ turn on dragging }
Label1.DragMode := dmManual;
Label1.ControlStyle := Label1.ControlStyle + [csDisplayDragImage];

type 
  // VCL needs this for getting drag images..
  TMyDragObject = class(TDragControlObject)
  protected
    function GetDragImages: TDragImageList; override; 
  end;

function TMyDragObject.GetDragImages: TDragImageList;
begin
  Result := Form1.ImageList1;
end;             

procedure TForm1.Label1MouseDown(...);
begin
  { start the dragging manually }
  Label1.BeginDrag(False, 4); // the problem area! image is shown instantly at here!
end;

procedure TForm1.Label1StartDrag(Sender: TObject; var DragObject: TDragObject);
var b : TBitmap;
begin
  ImageList1.Clear;
  DragObject := TMyDragObject.Create(self);

  b := TBitmap.Create;
  try
    b.Width := ImageList1.Width;
    b.Height := ImageList1.Height;
    b.LoadFromFile('/path/to/image');
    ImageList1.Add(b, nil);
  finally
    b.Free;
  end;
end;

procedure TForm1.Label1MouseMove(...);
begin
  if X > Label1.Width div 2 then // right half
    // ??? - do show the drag image
  else
    // ??? - no drage image should be shown
end;
Was it helpful?

Solution 3

As the silence on the topic implies, I suppose what I want is a little bit over the top for the default VCL drag&drop utilities.

Anyway, to get the desired effect - that is to have more control over dragging operation, here's a way that involves capturing the mouse and processing the messages manually:

  SetCapture(Handle);
  try
    while GetCapture = Handle do 
       { Process messages like mouse move, click, etc..
         ie. Change the drag image when the control under cursor changes.. } 
  finally
    if Handle = GetCapture then
      ReleaseCapture;
  end;

OTHER TIPS

Make the TBitmap, named b, a global variable and remove the line

ImageList1.Add(b, nil);

from the Label1StartDrag procedure and place it in an OnDragOverProcedure. This will allow ImageList1 to remain blank until the mouse has moved the four pixels specified in

Label1.BeginDrag(False, 4);

Label1.DragMode := dmAutomatic;

Have you tried to use dmManual? You should write some more code, but you can change more of the process.

By the way, why do you want to change standard behaviour? Your users probably expect the standard and can become frustrated if the program behaves differently.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top