【问题标题】:Delphi drag images challenge德尔福拖动图像挑战
【发布时间】:2009-03-19 14:37:23
【问题描述】:

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

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

到目前为止,我还没有找到解决方案 - 图像会立即显示(除非我修改 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;

【问题讨论】:

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


    【解决方案1】:

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

    ImageList1.Add(b, nil);

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

    中指定的四个像素

    Label1.BeginDrag(False, 4);

    【讨论】:

    • 不错的技巧,谢谢。虽然我必须补充一点,但这也不能让您对边界检查有太多控制,除了只是一个阈值。
    【解决方案2】:

    Label1.DragMode := dmAutomatic;

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

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

    【讨论】:

    • 嗨,我的错 - 它应该是 dmManual。
    • 问题其实要复杂的多,我只是简化一下来演示一下。
    【解决方案3】:

    正如主题的沉默所暗示的那样,我想我想要的对于默认的 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;
    

    【讨论】:

    • 这似乎是错误的——当你进入 while 循环时,捕获已经被释放,所以不应调用 finally 中的 ReleaseCapture()。
    • @mghie:这适用于循环中调用的“break”或“exit”情况。
    • 但是在 finally 块中检查捕获的窗口似乎是个好主意。感谢您的提醒。
    猜你喜欢
    • 2014-07-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多