Domanda

Il codice seguente abilita un controllo (un'etichetta per esempio) a mostrare le immagini di trascinamento durante l'operazione di trascinamento.

Il mio problema è che non voglio non mostrare istantaneamente l'immagine di trascinamento quando inizia il trascinamento, voglio che l'immagine venga visualizzata quando il mouse si trova su limiti specifici del controllo - ad es. nella metà destra dell'etichetta.

Finora non sono stato in grado di trovare una soluzione per questo: l'immagine viene visualizzata immediatamente (a meno che non modifichi la sorgente VCL). Apprezzo qualsiasi trucco a questo punto per ottenere il comportamento desiderato prima di abbandonare VCL trascina & Amp; rilascia utilità e lancia uno personalizzato catturando il mouse.

Ecco un pseudocodice di esempio per abilitare le immagini di trascinamento per un'etichetta ..

{ 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;
È stato utile?

Soluzione 3

Come suggerisce il silenzio sull'argomento, suppongo che ciò che voglio sia un po 'esagerato per l'utilità di trascinamento & predefinita VCL;

Ad ogni modo, per ottenere l'effetto desiderato, ovvero avere un maggiore controllo sull'operazione di trascinamento, ecco un modo che prevede l'acquisizione del mouse e l'elaborazione manuale dei messaggi:

  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;

Altri suggerimenti

Rendi la TBitmap, chiamata b, una variabile globale e rimuovi la linea

  
    

ImageList1.Add (b, nil);

  

dalla procedura Label1StartDrag e posizionarlo in un OnDragOverProcedure. Ciò consentirà a ImageList1 di rimanere vuoto fino a quando il mouse non sposta i quattro pixel specificati in

  
    

Label1.BeginDrag (False, 4);

  
  

Label1.DragMode: = dmAutomatic;

Hai provato a usare dmManual? Dovresti scrivere ancora un po 'di codice, ma puoi cambiare più del processo.

A proposito, perché vuoi cambiare il comportamento standard? I tuoi utenti probabilmente si aspettano lo standard e possono sentirsi frustrati se il programma si comporta diversamente.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top