德尔福拖动图像挑战

时间:2009-03-19 14:37:23

标签: delphi image drag-and-drop draggable vcl

下面的代码允许控件(例如标签)在拖动操作时显示拖动图像。

我的问题是我想要在拖动开始时立即显示拖动图像,我希望图像显示鼠标位于特定边界时控制 - 例如。在标签的右半部分。

到目前为止,我还没有找到解决方案 - 图像会立即显示(除非我修改VCL源)。我很欣赏这一点上的任何技巧,以便在放弃VCL拖放实用程序并滚动捕获鼠标的自定义工具之前获得所需的行为。

这是一个示例伪代码,用于为标签启用拖动图像。

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

3 个答案:

答案 0 :(得分:1)

将名为b的TBitmap设为全局变量并删除行

  
    

ImageList1.Add(b,nil);

  
从Label1StartDrag过程

并将其放在OnDragOverProcedure中。 这将允许ImageList1保持空白,直到鼠标移动了

中指定的四个像素
  
    

Label1.BeginDrag(False,4);

  

答案 1 :(得分:0)

  

Label1.DragMode:= dmAutomatic;

您是否尝试过使用dmManual?您应该编写更多代码,但是您可以更改更多的过程。

顺便问一下,为什么要改变标准行为?您的用户可能期望标准,如果程序行为不同,可能会感到沮丧。

答案 2 :(得分:0)

由于关于该主题的沉默暗示,我认为我想要的是默认的VCL拖放实用程序的顶部。

无论如何,为了获得理想的效果 - 即对拖动操作有更多的控制权,这里有一种涉及捕获鼠标并手动处理消息的方法:

  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;