![]() |
Dateien per IDropTarget öffnen.
Hallo
ich möchte mehrere Dateien aus dem Exlorer mit Rechtsklick öffnen. Es gibt 3 möglichkeiten. 1. paramstr 2. Dynamic Data Exchange (DDE) 3. COM and IDropTarget, by using a DropTarget key ![]() paramstr geht bei mir nur mit einer Datei. DDE habe ich auch zum laufen gebracht mit diesem Beispiel ![]() es ist möglich mehrere Dateien gleichzeitig zu öffnen. aber ab einer bestimmten anzahl kommt eine windows warnung, das das öffnen sehr lange dauern kann. was es auch tut (mind 0,5sec pro Datei (3ghz C2D)). Mit diesem Beispiel ist es möglich Dateien per OLE Drag&Drop in das eigene anwendungsfenster schieben. Zum testen habe ich einfach die Winamp.exe gegen diese Programmdatei ausgetauscht. beim öffen friert der explorer für einige zeit ein das programm öffnet sich, aber es landen keine einträge ins fenster. Hat jemand ein Funktionierendes beispiel?? mit passenden registry einstellungen.
Delphi-Quellcode:
{ ************************************************** **************
Source File Name : ExplorerDragDropFrm.pas Typ : Hauptformular Autor : Andreas Kosch Compiler : Delphi 4.02 CSS Betriebssystem : Windows 98 Beschreibung : Dateien via OLE Drag&Drop vom Explorer übernehmen. ************************************************** ************** } //unit ExplorerDragDropFrm; unit drag; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ComCtrls, ActiveX, ShlObj, ComObj, ShellAPI; type TForm1 = class(TForm, IDropTarget) ListBox1: TListBox; StatusBar1: TStatusBar; procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); private { Private-Deklarationen } public { Public-Deklarationen } // IDropTarget function DragEnter(const dataObj: IDataObject; grfKeyState: Longint; pt: TPoint; var dwEffect: Longint): HResult; stdcall; function DragOver(grfKeyState: Longint; pt: TPoint; var dwEffect: Longint): HResult; stdcall; function DragLeave: HResult; stdcall; function Drop(const dataObj: IDataObject; grfKeyState: Longint; pt: TPoint; var dwEffect: Longint): HResult; stdcall; end; var Form1: TForm1; implementation {$R *.DFM} procedure TForm1.FormCreate(Sender: TObject); begin OleInitialize(nil); OleCheck(RegisterDragDrop(Handle, Self)); end; procedure TForm1.FormDestroy(Sender: TObject); begin RevokeDragDrop(Handle); OleUninitialize; end; {-----------------------------------------------------------------} { IDropTarget-Implementierung } {-----------------------------------------------------------------} function TForm1.DragEnter(const dataObj: IDataObject; grfKeyState: Longint; pt: TPoint; var dwEffect: Longint): HResult; begin dwEffect := DROPEFFECT_COPY; Result := S_OK; end; function TForm1.DragOver(grfKeyState: Longint; pt: TPoint; var dwEffect: Longint): HResult; begin dwEffect := DROPEFFECT_COPY; Result := S_OK; end; function TForm1.DragLeave : HResult; begin Result := S_OK; end; function TForm1.Drop(const dataObj: IDataObject; grfKeyState: Longint; pt : TPoint; var dwEffect : Longint): HResult; var aFmtEtc : TFORMATETC; aStgMed : TSTGMEDIUM; szBuffer : array[0..MAX_PATH] of Char; i, iCount : Integer; begin ListBox1.Items.Clear; if (dataObj = nil) then raise Exception.Create('IDataObject-Zeiger ist ungültig!'); with aFmtEtc do begin cfFormat := CF_HDROP; ptd := nil; dwAspect := DVASPECT_CONTENT; lindex := -1; tymed := TYMED_HGLOBAL; end; OleCheck(dataObj.GetData(aFmtEtc, aStgMed)); try FillChar(szBuffer, SizeOf(szBuffer), #0); iCount := DragQueryFile(aStgMed.hGlobal, $FFFFFFFF, @szBuffer, MAX_PATH); for i := 0 to iCount - 1 do begin DragQueryFile(aStgMed.hGlobal, i, @szBuffer, MAX_PATH); ListBox1.Items.Add(szBuffer); end; finally ReleaseStgMedium(aStgMed); end; Result := S_OK; end; end. |
Re: Dateien per IDropTarget öffnen.
Ich hab jetzt nicht richtig verstanden, was du überhaupt willst, aber ich versuch mal zu antworten... :wink:
1. Gegenfrage: Warum funktioniert ParamStr nicht mit mehreren Dateien?
Delphi-Quellcode:
Das müsste eigentlich immer funzen (damit hast du alle Parameter in einer StringList...
for i:=0 to ParamCount-1 do
StringListe.Add(ParamStr(i)); Wegen dem "ins Prog ziehen"... wäre ![]() Naja, ich hoffe ich konnte wenigstens ein bisschen weiterhelfen... |
Re: Dateien per IDropTarget öffnen.
ParamStr öffnet mind 1 Datei aber auch 2-3 .aber nicht mehr
mein Code
Delphi-Quellcode:
// Wurde das Programm mit einem Parameter aufgerufen (zb öffnen mit)
// Nur dann wenn Anwedung neu gestartet wird procedure TFMainForm.FormShow(Sender: TObject); var n : integer; begin if (paramcount > 0) then begin for n := 1 to paramcount do begin if FileExists(paramstr(n)) then Playlist.items.Add(paramstr(n)); end; Play1; //Sofort abspielen end; end; //Dateien öffnen wenn Anwendung schon läuft procedure TFMainForm.OneInstance1GetParams(Sender: TObject; const Args: array of String); var i: Integer; begin for i := 0 to High(Args) do if (i > 0) and FileExists(Args[i]) then Playlist.items.Add(Args[i]); end; //Anwendung darf nur einmal gestartet werden procedure TFMainForm.OneInstance1Allow(Sender: TObject; var Allow: Boolean); begin Allow := false; end; Ich möchte zb. 100 dateien im exlorer markieren und dann wie in winamp (Play oder Enqueue) alle in mein progamm einfügen. PS. Ich habe mir einen MP3 player mit bass.dll programmiert. |
Re: Dateien per IDropTarget öffnen.
Delphi-Quellcode:
Das wäre zumindest mein Vorschlag (siehe 1. Zeile und 6. Zeile).
procedure TFMainForm.FormCreate(Sender: TObject);
var n : integer; begin if (paramcount > 0) then begin for n := 1 to paramcount-1 do begin if FileExists(paramstr(n)) then Playlist.items.Add(paramstr(n)); end; Play1; //Sofort abspielen end; end; Kannst du überprüfen, ob es daran liegt, dass die Dateien nicht in die Playlist aufgenommen werden, oder dass sie bloß nicht abgespielt werden? Also ich mein: Bist du dir sicher, dass es an der ParamStr-Sache liegt? |
Re: Dateien per IDropTarget öffnen.
Hallo,
wenn Du eine Implementation von IDropTarget benötigst, schau Dir mal meine ![]() Zitat:
Gruß xaromz |
Re: Dateien per IDropTarget öffnen.
Zitat:
Ich dachte nur, weil Delphi ja immer bei Null anfängt zu zählen, dass der Programmname bei ParamCount mitgezählt wird (weil es ja ParamStr(0) ist... :oops: Naja, da weis ich nun auch nicht weiter... |
Re: Dateien per IDropTarget öffnen.
Da bin ich wieder zu hause.
Wenn ich unter start ausführen die parameter manuell eingebe zb. "C:\Delphi MP3\Mp3Player.exe" test1 test2 test3 test4 test5 werden alle parameter übergeben. (Max 255 zeichen). Windows übergibt max 2 bis 3 dateinamen. @xaromz Deine komponente habe ich schon getestet(letzer beitrag). Funktioniert auch bis auf version 1.2 (delphi 7). Drag&Drop vom exlorer geht. aber wie bekomme ich die dateien zb mit öffnentest ins programm. Zum testen habe ich meine .exe mit der von winamp ausgetauscht. Als Beispiel Registry eintrag von winamp.
|
Re: Dateien per IDropTarget öffnen.
Ich bin noch am Hilfe lesen. Clsid usw.
|
Re: Dateien per IDropTarget öffnen.
Wie bekomme ich die clsid (guid) vom IDropTarget heraus?
bei verwendung von ShellDropper.pas |
Re: Dateien per IDropTarget öffnen.
Es klappt!!
Die function Drop habe ich kopiert. Der rest durch rumprobieren in Delphi.
Delphi-Quellcode:
unit Unit2;
{$WARN SYMBOL_PLATFORM OFF} interface uses Windows, ActiveX, Classes,ComObj,SysUtils,ShellAPI; type Ttest1 = class(TComObject,IDropTarget) public function DragEnter(const dataObj: IDataObject; grfKeyState: Longint; pt: TPoint; var dwEffect: Longint): HResult; stdcall; function DragOver(grfKeyState: Longint; pt: TPoint; var dwEffect: Longint): HResult; stdcall; function DragLeave: HResult; stdcall; function Drop(const dataObj: IDataObject; grfKeyState: Longint; pt: TPoint; var dwEffect: Longint): HResult; stdcall; end; const Class_test1: TGUID = '{35F45D48-100C-4603-AA40-D10516B07704}'; implementation uses ComServ, unit1 ; function Ttest1.DragEnter(const dataObj: IDataObject; grfKeyState: Longint; pt: TPoint; var dwEffect: Longint): HResult; stdcall; begin end; function Ttest1.DragOver(grfKeyState: Longint; pt: TPoint; var dwEffect: Longint): HResult; stdcall; begin end; function Ttest1.DragLeave: HResult; stdcall; begin end; function Ttest1.Drop(const dataObj: IDataObject; grfKeyState: Longint; pt: TPoint; var dwEffect: Longint): HResult; stdcall; var aFmtEtc : TFORMATETC; aStgMed : TSTGMEDIUM; szBuffer : array[0..MAX_PATH] of Char; i, iCount : Integer; begin Form1.ListBox1.Items.Clear; if (dataObj = nil) then raise Exception.Create('IDataObject-Zeiger ist ungültig!'); with aFmtEtc do begin cfFormat := CF_HDROP; ptd := nil; dwAspect := DVASPECT_CONTENT; lindex := -1; tymed := TYMED_HGLOBAL; end; OleCheck(dataObj.GetData(aFmtEtc, aStgMed)); try FillChar(szBuffer, SizeOf(szBuffer), #0); iCount := DragQueryFile(aStgMed.hGlobal, $FFFFFFFF, @szBuffer, MAX_PATH); for i := 0 to iCount - 1 do begin DragQueryFile(aStgMed.hGlobal, i, @szBuffer, MAX_PATH); Form1.ListBox1.Items.Add(szBuffer); end; finally ReleaseStgMedium(aStgMed); end; Result := S_OK; end; initialization TComObjectFactory.Create(ComServer, Ttest1, Class_test1, 'test1', 'test1', ciMultiInstance, tmApartment); end. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:27 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz