Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   DropStream als Datei speichern ? (https://www.delphipraxis.net/45782-dropstream-als-datei-speichern.html)

Orbmu2k 12. Mai 2005 10:14


DropStream als Datei speichern ?
 
Ich stehe vor einem Problem ich bekomme es einfach nicht in Gang einen DropStream von einem fremden Programm (Notes Mail) in einer Datei zu speichern.

Ich muss auch sagen das ich nicht wirklich weiter komme mit den Bespielen die es da so gibt. Diese Verarbeiten immer nur reinen Text und keinen Stream.

Hier ist mein bisheriger Code... er nimmt den Drop zwar an aber scheitertert dann mit der Fehlermeldung "Invalid FORMATETC structure"

Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ComCtrls, ActiveX, ShlObj, ComObj, StdCtrls;

type
  TfrmTPDrop = class(TForm, IDropTarget)
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
     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;
   function _AddRef: Integer; stdcall;
   function _Release: Integer; stdcall;
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  frmTPDrop: TfrmTPDrop;


implementation

{$R *.dfm}

uses
  ShellAPI;

procedure SaveDropDataToFile(Data:Pointer;Filename: String);
var
  fs: TFileStream;
  sa: IStream;
begin
  fs := TFileStream.Create(Filename,fmCreate);
  try
    sa := TStreamAdapter.Create(fs, soReference) as IStream;
    sa.Read(Data,SizeOf(Data),0);
  finally
    fs.Free;
  end;
end;

function TfrmTPDrop.DragEnter(const dataObj: IDataObject;
  grfKeyState: Integer; pt: TPoint; var dwEffect: Integer): HResult;
begin
  dwEffect := DROPEFFECT_COPY;
  Result := S_OK;
end;

function TfrmTPDrop.DragLeave: HResult;
begin
  Result := S_OK;
end;

function TfrmTPDrop.DragOver(grfKeyState: Integer; pt: TPoint;
  var dwEffect: Integer): HResult;
begin
  dwEffect := DROPEFFECT_COPY;
  Result := S_OK;
end;

function TfrmTPDrop.Drop(const dataObj: IDataObject; grfKeyState: Integer;
  pt: TPoint; var dwEffect: Integer): HResult;
var
  aFmtEtc: TFORMATETC;
  aStgMed: TSTGMEDIUM;
  pData: Pointer;
begin
  if (dataObj = nil) then
    raise Exception.Create('IDataObject-Pointer is not valid!');

  with aFmtEtc do
  begin
    cfFormat := CF_RIFF ;
    ptd := nil;
    dwAspect := DVASPECT_CONTENT;
    lindex := -1;
    tymed := TYMED_ISTREAM ;
  end;
  OleCheck(dataObj.GetData(aFmtEtc, aStgMed));
  try
    pData := GlobalLock(aStgMed.hGlobal);
    SaveDropDataToFile(pData,'c:\stream.doc');
  finally
    GlobalUnlock(aStgMed.hGlobal);
    ReleaseStgMedium(aStgMed);
  end;
  Result := S_OK;
end;

procedure TfrmTPDrop.FormCreate(Sender: TObject);
begin
  OleInitialize(nil);
  OleCheck(RegisterDragDrop(Handle, Self));
end;

procedure TfrmTPDrop.FormDestroy(Sender: TObject);
begin
  RevokeDragDrop(Handle);
  OleUninitialize;
end;

function TfrmTPDrop._AddRef: Integer;
begin
  Result := 1;
end;

function TfrmTPDrop._Release: Integer;
begin
  Result := 1;
end;



end.
Irgendwie ist mir das zu hoch :(

Jens Schumann 16. Mai 2005 15:26

Re: DropStream als Datei speichern ?
 
Hallo,
hier kommt meine Vermutung
Delphi-Quellcode:
OleCheck(dataObj.GetData(aFmtEtc, aStgMed));
  try
    pData := GlobalLock(aStgMed.stm); // <--- Schreib hier mal sStgMed.stm (Du forderst ja einen Stream an)
    SaveDropDataToFile(pData,'c:\stream.doc');
  finally
    GlobalUnlock(aStgMed.stm); // <--- Schreib hier mal sStgMed.stm
    ReleaseStgMedium(aStgMed);
  end;
Das Formular muss nur die Teile des IDropTarget implementieren, die noch nicht vorhanden sind.
Da alle Objekte ab TComponent das IUnknwon Interface unterstützen kannst Du Dir die Implementation AddRef und ReleaseRef sparen. Außdem sieht Deine Implentation der Methoden nicht so aus, als ob die einen Referenzzähler hoch oder runter zählen

Delphi-Quellcode:
procedure SaveDropDataToFile(Data:Pointer;Filename: String);
var
  fs: TFileStream;
  sa: IStream;
begin
  fs := TFileStream.Create(Filename,fmCreate);
  try
    sa := TStreamAdapter.Create(fs, soReference) as IStream;
    sa.Write(Data,SizeOf(Data),0); // <--- Hier sollte write stehen. Schließlich soll hier ja in den Stream geschrieben werden
  finally
    fs.Free;
  end;
end;
Evt solltest Du hier unter Registered Clipboard Formats nach schauen. CF_RIFF kommt mir irgendwie nicht ganz richtig vor.


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