AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Virtual Treeview und Drag'n'Drop

Ein Thema von Prototypjack · begonnen am 23. Dez 2007 · letzter Beitrag vom 24. Dez 2007
Antwort Antwort
Prototypjack

Registriert seit: 2. Feb 2003
611 Beiträge
 
Delphi 2009 Professional
 
#1

Virtual Treeview und Drag'n'Drop

  Alt 23. Dez 2007, 14:13
Moin,

So, nachdem ich jetzt schon einige Stunden an diesem Problem hänge, dachte ich mir, ich frage hier mal nach:

Ich habe in einem Projekt von mir zwei Virtual Treeviews (Eines links, das andere rechts). Die fertige Funktion der beiden sollte dann so aussehen: Die Items im rechten vst sollen per Drag'n'Drop verschoben werden(funktioniert bereits) und man soll Items aus dem Linken dem Rechten hinzufügen können(das Linke soll nichts können, außer diese Nodes wegzuschicken, um das Rechte weiter zu füllen).

Wie bereits gesagt, habe ich bereits 50% fertig. Denn alle Move-Operationen funktionieren perfekt. Nur wenn es dann an's Kopieren geht, habe ich einfach keine Ahnung wie ich an die Daten komme, um sie im neuen Node des rechten Vsts einzufügen.
(Achja, ich arbeite mit der OLE-Drag-Version. Sollte die VCL-Drag-Version für meine Zwecke besser geeignet sein, so lasst es mich bitte wissen!).

Hier mal was ich schon habe:
Delphi-Quellcode:
procedure TFrmSmartBarDlg.InsertData(Sender: TVirtualStringTree; DataObject:
  IDataObject; Formats: TFormatArray; Effect: Integer; Mode: TVTNodeAttachMode);
var
  FormatAccepted: Boolean;
  I: Integer;
begin
  FormatAccepted := False;
  for I := 0 to High(Formats) do
  begin
    if Formats[I] = CF_VIRTUALTREE then
    begin
      if not FormatAccepted then
      begin
        Sender.ProcessDrop(DataObject, Sender.DropTargetNode, Effect, Mode);
        FormatAccepted := True;
      end;
    end;
  end;
end;

procedure TFrmSmartBarDlg.vstRightDragDrop(Sender: TBaseVirtualTree;
  Source: TObject; DataObject: IDataObject; Formats: TFormatArray;
  Shift: TShiftState; Pt: TPoint; var Effect: Integer; Mode: TDropMode);

  procedure DetermineEffect;
  begin
    // Set Effect accordingly.
    if Source = Sender then
    begin
      Effect := DROPEFFECT_MOVE;
    end
    else
    begin
      Effect := DROPEFFECT_COPY;
    end;
  end;

var
  Attachmode: TVTNodeAttachMode;
  Nodes: TNodeArray;
begin
  Nodes := nil;
  // Translate the drop position into an node attach mode.
  case Mode of
    dmAbove:
      AttachMode := amInsertBefore;
    dmOnNode:
      AttachMode := amInsertAfter;
    dmBelow:
      AttachMode := amInsertAfter;
  else
    AttachMode := amNowhere;
  end;

  if DataObject <> nil then
  begin
    // OLE drag'n drop. Perform full processing.


    // Determine action in advance even if we don't use the dropped data.
    // Note: The Effect parameter is a variable which must be set to the action we
    // will actually take, to notify the sender of the drag operation about remaining actions.
    // This value determines what the caller will do after the method returns,
    // e.g. if DROPEFFECT_MOVE is returned then the source data will be deleted.
    DetermineEffect;
    InsertData(Sender as TVirtualStringTree, DataObject, Formats, Effect, AttachMode);
  end;
end;
Als Clipboard-Format ist Virtual Tree Data gewählt, der DragType ist, wie bereits gesagt dtOLE und der DragMode ist dmAutomatic.

Ich hoffe ihr könnt mir aus meiner Verzweiflung wieder hinaushelfen

Edit: Achja, das Kopieren des Nodes an sich funktioniert ja, das heißt, ich habe dann ein komplett leeres Node, an der Stelle wo ich das gezogenen einfügen wollte. Das Problem, welches sich mir stellt ist einfach wie ich an die Daten komme(die in Form eines Records vorliegen) und jene dann weiterleite, bzw. dem neuen Node anhänge.

Edit2: Auch die Suche hier um Forum und bei Mike direkt gibt nur sehr wenig her. Und falls ich mal was zu dem Thema finde, ist es entweder genau das, was ich nicht brauche, oder einfach unbeantwortet. Ebenfalls ist die Demo für meine Zwecke unbrauchbar, denn diese kopiert nur die Captions an sich, da ich aber mehrere Daten speichere, brauche ich direkt den Zugriff auf den betreffenden Record.

Danke schonmal & Grüße,
Max
Max
„If you have any great suggestions, feel free to mail me, and I'll probably feel free to ignore you.“ . Linus Torvalds
  Mit Zitat antworten Zitat
ManfredG

Registriert seit: 12. Feb 2007
Ort: Berlin
34 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#2

Re: Virtual Treeview und Drag'n'Drop

  Alt 23. Dez 2007, 14:48
hi max,
ich habe etwas ähnliches, verwende aber zum kopieren / verschieben im gleichen prog nicht OLE.

Folgendes prinzip:
im quellensteuerelement wird mit OnMouseDown festgehalten, wo die maustaste gedrückt wird.
gleichzeitig gehen die daten, die zu verschieben sind in einen record (als zwischenspeicher).
dann überprüfe ich in OnMouseMove, ob die maus bei gedrückter taste gezogen wird.
entfernt sich die maus um einen bestimmten betrag von der stelle, wo geklickt wurde, wird im record ein kennzeichen gesetzt, daß einen dragoperation im gange ist.

wird nun die maustaste im zweiten steuerelement losgelassen, so kann man dort erfahren, daß sie aus dem ersten steuerelement gezogen wurde. der punkt, an dem sie losgelassen wurde ist das ziel und dorthin werden die daten aus dem record übernommen.

das ganze funktioniert ohne alle drag&drop-methoden.
nur noch eine kleine ergänzung ist sinnvoll: ich setze einen HOOK für die maus, um von jeder stelle zu erfahren, ob die maus gehengelassen wurde. letzteres hat zur folge, daß im record das kennzeichen zurückgesetzt wird, durch das man erfährt, daß eine dragoperation im gange ist.

manfred
Manfred Götze
  Mit Zitat antworten Zitat
Prototypjack

Registriert seit: 2. Feb 2003
611 Beiträge
 
Delphi 2009 Professional
 
#3

Re: Virtual Treeview und Drag'n'Drop

  Alt 23. Dez 2007, 16:22
Zitat von ManfredG:
hi max,
ich habe etwas ähnliches, verwende aber zum kopieren / verschieben im gleichen prog nicht OLE.

Folgendes prinzip:
im quellensteuerelement wird mit OnMouseDown festgehalten, wo die maustaste gedrückt wird.
gleichzeitig gehen die daten, die zu verschieben sind in einen record (als zwischenspeicher).
dann überprüfe ich in OnMouseMove, ob die maus bei gedrückter taste gezogen wird.
entfernt sich die maus um einen bestimmten betrag von der stelle, wo geklickt wurde, wird im record ein kennzeichen gesetzt, daß einen dragoperation im gange ist.

wird nun die maustaste im zweiten steuerelement losgelassen, so kann man dort erfahren, daß sie aus dem ersten steuerelement gezogen wurde. der punkt, an dem sie losgelassen wurde ist das ziel und dorthin werden die daten aus dem record übernommen.

das ganze funktioniert ohne alle drag&drop-methoden.
nur noch eine kleine ergänzung ist sinnvoll: ich setze einen HOOK für die maus, um von jeder stelle zu erfahren, ob die maus gehengelassen wurde. letzteres hat zur folge, daß im record das kennzeichen zurückgesetzt wird, durch das man erfährt, daß eine dragoperation im gange ist.

manfred
Uiui, das klingt aber irgendwie, naja, sehr umständlich (der Hook besonders). Es muss doch irgendwie mit Bordmitteln zu lösen sein. Ich werd' wahnsinnig

Grüße & Hilfe,
Max
Max
„If you have any great suggestions, feel free to mail me, and I'll probably feel free to ignore you.“ . Linus Torvalds
  Mit Zitat antworten Zitat
ManfredG

Registriert seit: 12. Feb 2007
Ort: Berlin
34 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#4

Re: Virtual Treeview und Drag'n'Drop

  Alt 23. Dez 2007, 18:29
alles ansichtssache, ich finde es zB etwas aufwendig, wenn ich windows für drag&drop
bemühen soll, solange alles in einem prog bleibt...
sonst aber garnicht so schlimm, wird dir gefallen...
ist nicht von mir, habe ich auch in DP gefunden.

im formular deklarieren:
Delphi-Quellcode:
  protected (z.B.)
    HookID : HHook;
    IsMouseDown: boolean;
...
in FormCreate:
(Formular heißt HF)

Delphi-Quellcode:
procedure THF.FormCreate(Sender: TObject);
...
  HookId:=SetWindowsHookEx(WH_MOUSE,MouseProc,0,GetCurrentThreadId());
...
dann eine funktion erstellen
Delphi-Quellcode:
// HOOK zur Feststellung von WM_LBUTTONDOWN und WM_LBUTTONUP auch
// außerhalb des Programmes (Es wird die Variable IsMouseDown gesetzt)
function MouseProc(nCode: Integer; wParam, lParam: Longint): Longint; stdcall;
begin
  case nCode < 0 of
  True:
    Result := CallNextHookEx(HF.HookID, nCode, wParam, lParam)
  else begin
    case wParam of
      WM_LBUTTONDOWN : HF.IsMouseDown:=TRUE;
      WM_LBUTTONUP : HF.IsMouseDown:=FALSE;
    end; { of case }
    Result := CallNextHookEx(HF.HookID, nCode, wParam, lParam); end
  end;
end;
und in FormClose wieder freigeben

Delphi-Quellcode:
procedure THF.FormClose(Sender: TObject; var Action: TCloseAction);
...
  if HookID <> 0 then UnHookWindowsHookEx(HookID);
...
gruß
Manfred Götze
  Mit Zitat antworten Zitat
ManfredG

Registriert seit: 12. Feb 2007
Ort: Berlin
34 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#5

Re: Virtual Treeview und Drag'n'Drop

  Alt 23. Dez 2007, 18:31
ps: das MouseUp wird auch dann erkannt, wenn sich die maus außerhalb des programmes befindet

Manfred
Manfred Götze
  Mit Zitat antworten Zitat
generic

Registriert seit: 24. Mär 2004
Ort: bei Hannover
2.415 Beiträge
 
Delphi XE5 Professional
 
#6

Re: Virtual Treeview und Drag'n'Drop

  Alt 23. Dez 2007, 20:24
klingt irgendwie alles kompliziert was ihr macht.

du hast doch im drop ereignis die variable source.
das ist der tree/obj aus dem die daten kommen.
also einfach testen ob das die gültige quelle ist.
in der gültigen quelle brauchst du dann doch nur die "selected" nodes auswerten und einfügen/kopieren.
Coding BOTT - Video Tutorials rund um das Programmieren - https://www.youtube.com/@codingbott
  Mit Zitat antworten Zitat
Prototypjack

Registriert seit: 2. Feb 2003
611 Beiträge
 
Delphi 2009 Professional
 
#7

Re: Virtual Treeview und Drag'n'Drop

  Alt 24. Dez 2007, 10:46
Zitat von generic:
klingt irgendwie alles kompliziert was ihr macht.

du hast doch im drop ereignis die variable source.
das ist der tree/obj aus dem die daten kommen.
also einfach testen ob das die gültige quelle ist.
in der gültigen quelle brauchst du dann doch nur die "selected" nodes auswerten und einfügen/kopieren.
In der Tat, mein Ansatz war wohl etwas, naja, kompliziert. Danke für deine Hilfe, auf diesem Wege hat es sofort und ohne Zwischenfälle geklappt.

Vor lauter Wald sieht man keine Bäume mehr, oder wie war das noch?

Danke & Grüße,
Max
Max
„If you have any great suggestions, feel free to mail me, and I'll probably feel free to ignore you.“ . Linus Torvalds
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 20:40 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz