Einzelnen Beitrag anzeigen

Jumpy

Registriert seit: 9. Dez 2010
Ort: Mönchengladbach
1.736 Beiträge
 
Delphi 6 Enterprise
 
#1

Drag&Drop im TTreeview mit eigenem Cursor

  Alt 5. Jun 2014, 18:11
Hallo,

es geht um Drag&Drop innerhalb eines TTreeViews, also um's verschieben oder kopieren (Wenn Strg gedrückt) von Nodes.

Das habe ich soweit hinbekommen, wobei ich beim OnDragDrop des TV über GetKeyState(VK_Control) feststelle, ob in dem Moment die Strg-Taste gedrückt ist.

Jetzt wollte ich auch, das ein anderer Cursor angezeigt wird. Dabei nutze ich die Informationen von hier. Arbeite also mit einem eigenen DragObject, was auch gut klappt, nutze als alternativen Cursor crMultiDrag, da ich zu faul war mir einen anderen zu malen.

Jetzt wollte ich aber auch mal versuchen (ebenfalls nach obiger Anleitung) den Text des gerade gedraggten Nodes neben dem Cursor anzuzeigen. Auch das klappt, allerdings kommt es beim "überfahren" von TTreenodes zu Artefaktbildung, d.h. der TreeView zeichnet sich nicht richtig (Siehe Bild)?

Woran könnte das legen, bzw. was muss ich machen? Im OnEndDrag rufe ich mittlerweile TV.Repaint auf, sonst würde der auch nach Ende des Drag&Drop-Vorganges so falsch gezeichnet bleiben.

Hier der relevante(?) Code soweit:
Delphi-Quellcode:
type
  TNodeDragObject = class(TDragControlObject)
   private
     fData:String;
     FX, FY: Integer;
     FDragImages: TDragImageList;
   protected
     function GetDragCursor(Accepted: Boolean; X, Y: Integer): TCursor; override;
     function GetDragImages: TDragImageList; override;
   public
     constructor Create(Control:TControl;Data:String; X, Y: Integer); reintroduce;
     destructor Destroy; override;
     property Data:String read fData;
  end;

constructor TNodeDragObject.Create(Control: TControl; Data: String; X, Y: Integer);
begin
  inherited create(Control);
  fData:=Data;
  FX:=X;
  FY:=Y;
end;

destructor TNodeDragObject.Destroy;
begin
  FDragImages.Free;
  inherited;
end;

function TNodeDragObject.GetDragCursor(Accepted: Boolean; X, Y: Integer): TCursor;
var i:integer;
begin
  i:=GetKeyState(VK_Control);
  if Accepted and ((i=-127)or(i=-128)) then
    Result := crMultiDrag
  else
    Result := inherited GetDragCursor(Accepted, X, Y)
end;

function TNodeDragObject.GetDragImages: TDragImageList;
var Bmp: TBitmap;
    BmpIdx: Integer;
begin
  if not Assigned(FDragImages) then
    FDragImages := TDragImageList.Create(nil);
  Result := FDragImages;
  Result.Clear;
  Bmp := TBitmap.Create;
  try
    //Make up some string to write on bitmap
    Bmp.Canvas.Font.Name := 'Arial';
    Bmp.Canvas.Font.Style := Bmp.Canvas.Font.Style + [fsItalic];
    Bmp.Height := Bmp.Canvas.TextHeight(Data);
    Bmp.Width := Bmp.Canvas.TextWidth(Data);
    //Fill background with olive
    Bmp.Canvas.Brush.Color := clOlive;
    Bmp.Canvas.FloodFill(0, 0, clWhite, fsSurface);
    //Write a string on bitmap
    Bmp.Canvas.TextOut(0, 0, Data);
    Result.Width := Bmp.Width;
    Result.Height := Bmp.Height;
    //Make olive pixels transparent, whilst adding bmp to list
    BmpIdx := Result.AddMasked(Bmp, clOlive);
    Result.SetDragImage(BmpIdx, FX, FY);
  finally
    Bmp.Free;
    Application.ProcessMessages;
  end
end;



procedure TMain.TVStartDrag(Sender: TObject; var DragObject: TDragObject);
var s:String;
    Pt:TPoint;
begin
   s:=(Sender as TTreeView).Selected.Text;
  FDragObject:=TNodeDragObject.Create(Sender as TTreeView,s,-10,0);
  DragObject:=FDragObject;
end;
Miniaturansicht angehängter Grafiken
tv.png  
Ralph

Geändert von Jumpy ( 5. Jun 2014 um 18:17 Uhr)
  Mit Zitat antworten Zitat