utku_karatas
utku_karatas

Reputation: 6295

Delphi drag images challenge

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;

Upvotes: 1

Views: 3850

Answers (3)

LuckyDog
LuckyDog

Reputation:

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);

Upvotes: 1

utku_karatas
utku_karatas

Reputation: 6295

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;

Upvotes: 0

Toon Krijthe
Toon Krijthe

Reputation: 53366

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.

Upvotes: 0

Related Questions