Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Bild per Drag and Drop ins Programm holen (https://www.delphipraxis.net/55922-bild-per-drag-drop-ins-programm-holen.html)

tobi1701 28. Okt 2005 21:55


Bild per Drag and Drop ins Programm holen
 
hallo,

ich habe eine Form, auf der ein TImage liegt. in dieses leere Image möchte ich gerne grafiken ziehen, zB aus dem browser oder dem explorer.
beim browser dürfte das format ja eigentlich keine rolle spielen, da es ja schon geöffnet ist, oder?
sollte aber auch egal sein, denn ich benutze die GraphicsEx-unit, mit der ja so ziemlich alle formate kompatibel sind.

aber jetzt die frage: wie geht das?
ich kann im ObjectInspector das ereignis .OnDragDrop auswählen (ist das das richtige?). doch was dann? ich habe Sender,Source:TObject, doch was genau ist das?
und was mich auch wundert ist, dass nichts passiert, wenn ich ein bild über das TImage dragge, bei anderen programmen, die diese eigenschaft unterstützen, ändert sich der cursor, oder das programm blinkt, etc.

leider habe ich auch mit der suche kein passendes beispiel gefunden, ich hoffe mir kann jemand helfen.

SirThornberry 28. Okt 2005 23:07

Re: Bild per Drag and Drop ins Programm holen
 
du brauchst ein Control mit Handle. Darauf musst du dann "DragAcceptFiles" anwenden damit es erlaubt das Dateien darauf angenommen werden (ansonsten erscheint ja das Parkverbot wenn man eine Datei irgendwo drauf zieht). Und dann musst du die Message "WM_DROPFILES" abfangen.

hier steht wie das ganze geht wenn du Dateien auf dein Formular ziehen willst (Quelltext):
http://www.delphipraxis.net/internal...=126249#126249

tobi1701 29. Okt 2005 00:02

Re: Bild per Drag and Drop ins Programm holen
 
hm, also prinzipiell funktioniert es schonmal damit (ich habe der einfachheit halber auch mal eine listbox auf die form gelegt, um es zu testen).

aber ich verstehe einige sachen nicht ganz:
Delphi-Quellcode:
DragQueryFile(Message.Drop, 0, @Buffer, SizeOf(Buffer));
ich kann DragQueryFile leider nicht in der hilfe finden und daher nur erahnen, was es tut. auch das @ ist mir etwas suspekt.

jedenfalls gibt es den pfad des 0.ten gedragten objektes an das Edit1.Text über die variable Buffer.
aber warum ausgerechnet den Pfad? steht das in der Message.Drop? und was genau ist Message? in der hilfe stehen viele sachen zu Message, aber wie genau kann ich herausfinden, was das ist?

Delphi-Quellcode:
Count := DragQueryFile(Message.Drop, UINT(-1), nil, 0);
an Count wird ja ganz offensichtlich übergeben, wie viele elemente gedraggt wurden, allerdings verstehe ich auch hier die zeile nicht. was ist UINT?

und können via Drag&Drop nur pfade, also nur strings übergeben werden? denn wenn ich zB aus dem browser ein bild auf mein programm droppe, erhält dann das programm die url und muss sich das bild "selbst herunterladen"?

edit: und wie kann ich zB filtern? ich möchte in meinem fall nur bilder auf die form ziehen, nicht aber andere dateien. wie kann ich erreichen, dass bei nicht-bildern dieser stop-schild cursor angezeigt wird, bzw. der drop-vorgang nicht stattfinden kann?

SirThornberry 29. Okt 2005 00:06

Re: Bild per Drag and Drop ins Programm holen
 
Ich hab eigentlich nirgendwo Message.Drop geschrieben, du scheinst dich also auf einen anderen Quelltext zu beziehen. DragQueryFile sollte es in deiner Hilfe geben. Allerdings ist es nicht in der Standardhilfedatei sondern in "MS SDK Help Files -> Win32 Programmer's Reference". Die Hilfe spiegelt also das MSDN wieder. Kurz und Knapp - DragQueryFile ist eine ApiFunktion.

Wenn bei DragQueryFile der zweite Parameter "$FFFFFFFF" ist so gibt die Funktion die Anzahl der gedroppten Dateien zurück. Die restlichen Parameter werden also ignoriert.

Gibt man als zweiten Paremter eine andere Zahl an steht diese für den Index der gedroppten Datei. Also 0 für die erste gedroppte Datei, 1 für die zweite gedroppte datei etc. Gibt man in diesem Zusammenhang als dritten Parameter "nil" an so gibt die Funktion die Länge des gedroppten Filenames zurück. Gibt man einen Wert ungleich "nil" an so wird der Buffer den man angibt mit dem Dateinamen gefüllt.

Zusammengefasst:
Delphi-Quellcode:
AnzahlDerGedropptenDateien := DragQueryFile(Msg.WParam, $FFFFFFFF, nil, 0);
Delphi-Quellcode:
DateinamenLaengeVonGedroppterDateiNummer2 := DragQueryFile(Msg.WParam, 1, nil, 0);
Delphi-Quellcode:
var LGedroppteDatei: String;
begin
  DateinamenLaengeVonGedroppterDateiNummer2 := DragQueryFile(Msg.WParam, 1, nil, 0) + 1;
  SetLength(LGedroppteDatei, DateinamenLaengeVonGedroppterDateiNummer2);
  SetLength(LGedroppteDatei, DragQueryFile(Msg.WParam, 1, @LGedroppteDatei[1],
                                           DateinamenLaengeVonGedroppterDateiNummer2));
  ShowMessage(LGedroppteDatei);
end;

tobi1701 29. Okt 2005 00:45

Re: Bild per Drag and Drop ins Programm holen
 
ja, danke, das ist wirklich sehr anschaulich.
allerdings ist mir nicht so ganz klar, woher man das wissen soll (ausser natürlich jemanden fragen, der das bereits weiss).
und ausserdem stellt sich ja jetzt die frage, wozu es diese ganzen Drag&Drop Events gibt, die man für jedes element im ObjectInspector sehen kann.

eine letzte frage direkt dazu habe ich aber noch:
und zwar bezieht sich das Drag&Drop jetzt ja auf die gesamte Form. ich möchte es aber auf ein bestimmtes element bezogen haben (wie oben genannt mein Image, oder jetzt wo ich weiss, wie einfach das auch mit listen zu handhaben ist, eine ListView). das muss doch auch möglich sein, denn es könnte ja auch sein, dass man 2 unterschiedliche ListBoxen hat, auf die man etwas ziehen kann.

Christian Seehase 29. Okt 2005 00:49

Re: Bild per Drag and Drop ins Programm holen
 
Moin SirThornberry,

Zitat:

Zitat von SirThornberry
Allerdings ist es nicht in der Standardhilfedatei sondern in "MS SDK Help Files -> Win32 Programmer's Reference". Die Hilfe spiegelt also das MSDN wieder.

allerdings ist der bei Delphi mitgelieferte Auszug (leider) nicht unbedingt sonderlich aktuell.
Besser man schlägt so etwas im MSDN nach oder lädt sich das PSDK herunter.

SirThornberry 29. Okt 2005 00:52

Re: Bild per Drag and Drop ins Programm holen
 
dieses WM_DROPFILES bezieht sich nur auf das Drag&Drop von Dateien. Die Events für Drag&Drop die fast jede Komponente hat beziehen sich hingegen auf das Drag&Drop zwischen den einzelnen Komponenten.
Zur anderen Frage: Das Drag&Drop von Dateien nur für ein TImage zu realisieren (und nicht für das ganze Form) geht nicht da TImage kein Handle hat. Die Message wird somit an das Fenster(Control) unter dem TImage geschickt welches ein Handle hat. Für TListbox und TListView (die haben ein Handle) geht es hingegen. Da gibt es 2 Möglichkeiten. Variante 1 ist das ableiten von einer bereits vorhandenen Komponente und diese mit dem entsprechenden Messagehandler erweitern). Variante2 ist das umbiegen der WindowProcedure der Komponente und somit das manuelle Abfangen der Message in der neuen WindowProcedure (gibt es einige Threads dazu).

Wenn du unbedingt willst das man auf ein TImage Dateien ziehen kann so lege einfach direkt unter das TImage ein Panel und fange auf diesem die Message ab.

variante1 (der Quelltext muss in die Unit wo TListBox das Droppen von Dateien unterstützen soll):
Delphi-Quellcode:
type
  TListBox = class(StdCtrls.TListBox)
  private
    procedure FWM_DropFiles(var Msg: TMessage); message WM_DROPFILES;
  end;
[...]
procedure TListBox.FWM_DropFiles(var Msg: TMessage);
var i, anzahl, size: integer;
    Dateiname: String;
    antwort: Integer;
begin
  inherited;
  Dateiname := '';
  anzahl := DragQueryFile(Msg.WParam, $FFFFFFFF, nil, 0);
  for i := 0 to (anzahl - 1) do
  begin
    size := DragQueryFile(Msg.WParam, i , nil, 0) + 1;
    SetLength(Dateiname, size);
    SetLength(Dateiname, DragQueryFile(Msg.WParam,i , @Dateiname[1], size));
    //hier dein source - in "Dateiname" ist der name des droped objectes
  end;
  DragFinish(Msg.WParam);
end;
und damit das ganze für die entsprechende Listbox geht muss natürlich noch folgendes gemacht werden:
Delphi-Quellcode:
DragAcceptFiles(ListBox1.Handle, True);

Zitat:

...allerdings ist mir nicht so ganz klar, woher man das wissen soll...
dafür gibt es das msdn (http://msdn.microsoft.com bzw. noch direkter http://msdn.microsoft.com/library ) dort kann man die Befehle suchen (man weiß ja ungefähr nach was man suchen muss) und die Parameter etc. sind dort auch zu finden mit deren Bedeutung.

tobi1701 29. Okt 2005 01:06

Re: Bild per Drag and Drop ins Programm holen
 
wow, das funktioniert ja prima. vielen dank, du hast mir wirklich sehr geholfen.

edit:
wo wir schonmal bei dem thema sind (hust), gibt es denn sowas wie eine TListBox für bilder? vielleicht auch als componente zum installieren? oder muss ich mir selber eine machen?
es wundert mich gerade, dass es sowas nicht standardmässig gibt, das wird doch bestimmt häufiger mal gebraucht....

SirThornberry 29. Okt 2005 01:23

Re: Bild per Drag and Drop ins Programm holen
 
eine Listbox für Bilder? Soll in der Listbox nur ein Bild ohne Text angezeigt werden? Wenn du vor dem Text ein Bild willst dann gibt es dafür ja TListView (ViewStyle := vsReport etc.)
Allgemeint gilt jedoch, neue Frage, neuer Thread (damit das ganze übersichtlich bleibt und man mit Hilfe der Suchfunktion auch die richtigen Themen findet)


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:29 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