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;
¿Fue útil?

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.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top