AGB  ·  Datenschutz  ·  Impressum  







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

Dateien per IDropTarget öffnen.

Ein Thema von Thomasl · begonnen am 24. Mär 2007 · letzter Beitrag vom 1. Apr 2007
Antwort Antwort
Seite 1 von 2  1 2      
Thomasl

Registriert seit: 19. Jun 2006
Ort: Vreden
66 Beiträge
 
Delphi 11 Alexandria
 
#1

Dateien per IDropTarget öffnen.

  Alt 24. Mär 2007, 18:18
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.
Thomas Levering
  Mit Zitat antworten Zitat
Benutzerbild von TonyR
TonyR

Registriert seit: 17. Jun 2006
Ort: Bautzen
503 Beiträge
 
FreePascal / Lazarus
 
#2

Re: Dateien per IDropTarget öffnen.

  Alt 24. Mär 2007, 19:38
Ich hab jetzt nicht richtig verstanden, was du überhaupt willst, aber ich versuch mal zu antworten...

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

Naja, ich hoffe ich konnte wenigstens ein bisschen weiterhelfen...
Es ist unmöglich, witzig zu sein ohne ein bisschen Bosheit. Die Bosheit eines guten Witzes ist der Widerhaken, der ihn haften lässt. - Georg Christoph Lichtenberg
  Mit Zitat antworten Zitat
Thomasl

Registriert seit: 19. Jun 2006
Ort: Vreden
66 Beiträge
 
Delphi 11 Alexandria
 
#3

Re: Dateien per IDropTarget öffnen.

  Alt 25. Mär 2007, 01:57
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.
Thomas Levering
  Mit Zitat antworten Zitat
Benutzerbild von TonyR
TonyR

Registriert seit: 17. Jun 2006
Ort: Bautzen
503 Beiträge
 
FreePascal / Lazarus
 
#4

Re: Dateien per IDropTarget öffnen.

  Alt 25. Mär 2007, 10:33
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?
Es ist unmöglich, witzig zu sein ohne ein bisschen Bosheit. Die Bosheit eines guten Witzes ist der Widerhaken, der ihn haften lässt. - Georg Christoph Lichtenberg
  Mit Zitat antworten Zitat
xaromz

Registriert seit: 18. Mär 2005
1.682 Beiträge
 
Delphi 2006 Enterprise
 
#5

Re: Dateien per IDropTarget öffnen.

  Alt 25. Mär 2007, 11:31
Hallo,

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

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
I am a leaf on the wind - watch how I soar
  Mit Zitat antworten Zitat
Benutzerbild von TonyR
TonyR

Registriert seit: 17. Jun 2006
Ort: Bautzen
503 Beiträge
 
FreePascal / Lazarus
 
#6

Re: Dateien per IDropTarget öffnen.

  Alt 25. Mär 2007, 11:35
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 ...
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...

Naja, da weis ich nun auch nicht weiter...
Es ist unmöglich, witzig zu sein ohne ein bisschen Bosheit. Die Bosheit eines guten Witzes ist der Widerhaken, der ihn haften lässt. - Georg Christoph Lichtenberg
  Mit Zitat antworten Zitat
Thomasl

Registriert seit: 19. Jun 2006
Ort: Vreden
66 Beiträge
 
Delphi 11 Alexandria
 
#7

Re: Dateien per IDropTarget öffnen.

  Alt 25. Mär 2007, 18:37
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}"
Thomas Levering
  Mit Zitat antworten Zitat
Thomasl

Registriert seit: 19. Jun 2006
Ort: Vreden
66 Beiträge
 
Delphi 11 Alexandria
 
#8

Re: Dateien per IDropTarget öffnen.

  Alt 26. Mär 2007, 19:11
Ich bin noch am Hilfe lesen. Clsid usw.
Thomas Levering
  Mit Zitat antworten Zitat
Thomasl

Registriert seit: 19. Jun 2006
Ort: Vreden
66 Beiträge
 
Delphi 11 Alexandria
 
#9

Re: Dateien per IDropTarget öffnen.

  Alt 28. Mär 2007, 21:57
Wie bekomme ich die clsid (guid) vom IDropTarget heraus?
bei verwendung von ShellDropper.pas
Thomas Levering
  Mit Zitat antworten Zitat
Thomasl

Registriert seit: 19. Jun 2006
Ort: Vreden
66 Beiträge
 
Delphi 11 Alexandria
 
#10

Re: Dateien per IDropTarget öffnen.

  Alt 1. Apr 2007, 00:16
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.
Thomas Levering
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


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 16:59 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