下面的代码允许控件(例如标签)在拖动操作时显示拖动图像。
我的问题是我不想要在拖动开始时立即显示拖动图像,我希望图像显示当鼠标位于特定边界时控制 - 例如。在标签的右半部分。
到目前为止,我还没有找到解决方案 - 图像会立即显示(除非我修改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;
答案 0 :(得分:1)
将名为b的TBitmap设为全局变量并删除行
从Label1StartDrag过程ImageList1.Add(b,nil);
并将其放在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;