Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Dateien per IDropTarget öffnen. (https://www.delphipraxis.net/89020-dateien-per-idroptarget-oeffnen.html)

Thomasl 24. Mär 2007 18:18


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
MSDN

paramstr geht bei mir nur mit einer Datei.
DDE habe ich auch zum laufen gebracht mit diesem Beispiel
Codegear.com Id=17787
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.

TonyR 24. Mär 2007 19:38

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:
for i:=0 to ParamCount-1 do
StringListe.Add(ParamStr(i));
Das müsste eigentlich immer funzen (damit hast du alle Parameter in einer StringList...

Wegen dem "ins Prog ziehen"... wäre der dazu passende Artikel von DSDT.info vielleicht auch was :zwinker:

Naja, ich hoffe ich konnte wenigstens ein bisschen weiterhelfen...

Thomasl 25. Mär 2007 01:57

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.

TonyR 25. Mär 2007 10:33

Re: Dateien per IDropTarget öffnen.
 
Delphi-Quellcode:
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;
Das wäre zumindest mein Vorschlag (siehe 1. Zeile und 6. Zeile).
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?

xaromz 25. Mär 2007 11:31

Re: Dateien per IDropTarget öffnen.
 
Hallo,

wenn Du eine Implementation von IDropTarget benötigst, schau Dir mal meine Komponente dazu an.

Zitat:

Zitat von TonyR
Das wäre zumindest mein Vorschlag (siehe 1. Zeile und 6. Zeile).

Zumindest die Zeile sechs ist falsch. ParamCount gibt die Anzahl der Parameter an, diese beginnen aber bei eins. ParamStr(0) ist nämlich der Programmname.

Gruß
xaromz

TonyR 25. Mär 2007 11:35

Re: Dateien per IDropTarget öffnen.
 
Zitat:

Zitat von xaromz
...Zumindest die Zeile sechs ist falsch. ParamCount gibt die Anzahl der Parameter an, diese beginnen aber bei eins. ParamStr(0) ist nämlich der Programmname.

Tatsache :shock: ...
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...

Thomasl 25. Mär 2007 18:37

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.

  • Windows Registry Editor Version 5.00

    [HKEY_CLASSES_ROOT\Winamp.File\shell\open]
    @="Öffnentest"

    [HKEY_CLASSES_ROOT\Winamp.File\shell\open\command]
    @="\"C:\\Programme\\Winamp\\winamp.exe\" \"%1\""

    [HKEY_CLASSES_ROOT\Winamp.File\shell\open\DropTarge t]
    "Clsid"="{46986115-84D6-459c-8F95-52DD653E532E}"

Thomasl 26. Mär 2007 19:11

Re: Dateien per IDropTarget öffnen.
 
Ich bin noch am Hilfe lesen. Clsid usw.

Thomasl 28. Mär 2007 21:57

Re: Dateien per IDropTarget öffnen.
 
Wie bekomme ich die clsid (guid) vom IDropTarget heraus?
bei verwendung von ShellDropper.pas

Thomasl 1. Apr 2007 00:16

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 09:01 Uhr.
Seite 1 von 2  1 2      

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