Desafío de imágenes de arrastre de Delphi
-
20-08-2019 - |
Pregunta
El siguiente código permite que un control (una etiqueta, por ejemplo) muestre imágenes de arrastre durante la operación de arrastre.
Mi problema es que no quiero mostrar la imagen de arrastre instantáneamente cuando comienza el arrastre, quiero que la imagen se muestre cuando el mouse está en límites específicos del control - ej. en la mitad derecha de la etiqueta.
Hasta ahora no he podido encontrar una solución para esto: la imagen solo se muestra instantáneamente (a menos que modifique la fuente VCL). Agradezco cualquier truco en este punto para obtener el comportamiento deseado antes de abandonar VCL arrastrar & Amp; soltar utilidades y rodar uno personalizado capturando el mouse.
Aquí hay un pseudocódigo de ejemplo para permitir arrastrar imágenes para una etiqueta ...
{ 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;
Solución 3
Como implica el silencio sobre el tema, supongo que lo que quiero es un poco exagerado para las utilidades predeterminadas VCL drag & amp; drop.
De todos modos, para obtener el efecto deseado, es decir, tener más control sobre la operación de arrastre, aquí hay una forma que implica capturar el mouse y procesar los mensajes manualmente:
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;
Otros consejos
Convierta el TBitmap, llamado b, en una variable global y elimine la línea
ImageList1.Add (b, nil);
del procedimiento Label1StartDrag y colóquelo en un OnDragOverProcedure. Esto permitirá que ImageList1 permanezca en blanco hasta que el mouse haya movido los cuatro píxeles especificados en
Label1.BeginDrag (Falso, 4);
Label1.DragMode: = dmAutomatic;
¿Has intentado usar dmManual? Debería escribir más código, pero puede cambiar más del proceso.
Por cierto, ¿por qué quieres cambiar el comportamiento estándar? Sus usuarios probablemente esperan el estándar y pueden sentirse frustrados si el programa se comporta de manera diferente.