gpt4 book ai didi

delphi - 从 Delphi 中的 IDataObject 检索文件名

转载 作者:行者123 更新时间:2023-12-02 21:59:26 26 4
gpt4 key购买 nike

我正在构建一个 Delphi XE3 应用程序,它需要能够将文件拖放到它上面。我的“资源管理器”>“应用程序”方面可以正常工作,但我一生都无法弄清楚从“应用程序”>“应用程序”转到“应用程序”时如何获取文件名。

假设从 Outlook(或任何其他应用程序)中删除了一个文件,只要我事先手动分配文件名,我就可以使用该文件。

SetFormatEtc( FormatEtc , CF_FILECONTENTS );
OleCheck( dataObj.GetData( FormatEtc , Medium ) );
OleStream := TOleStream.Create( IUnknown( Medium.stm ) as IStream );
MemStream := TMemoryStream.Create;
OleStream.Position := 0;
MemStream.CopyFrom( OleStream , OleStream.Size );

TMemoryStream( MemStream ).SaveToFile( 'C:\' + filename );

MemStream.Free;
OleStream.Free;
ReleaseStgMedium( Medium );

最佳答案

CF_FILECONTENTS格式可以包含多个流。您必须检查 CF_FILEDESCRIPTORW 和 CF_FILEDESCRIPTORA 格式以检测流计数和流名称。一些来源:

function ContainFormat(ADataObject: IDataObject; AFormat: TClipFormat;
ATymed: Longint; AAspect: LongInt = DVASPECT_CONTENT; AIndex: LongInt = -1): Boolean;
var Format: TFormatEtc;
begin
ZeroMemory(@Format, SizeOf(Format));
Format.cfFormat := AFormat;
Format.dwAspect := AAspect;
Format.lindex := AIndex;
Format.tymed := ATymed;
Result := ADataObject.QueryGetData(Format) = S_OK;
end;

procedure InvalidMedium;
begin
raise Exception.Create('Invalid medium');
end;

function ExtractStream(ADataObject: IDataObject; AIndex: Integer): IStream;
var Format: TFormatEtc;
Medium: TStgMedium;
begin
ZeroMemory(@Format, SizeOf(Format));
Format.cfFormat := CF_FILECONTENTS;
Format.dwAspect := DVASPECT_CONTENT;
Format.lindex := AIndex;
Format.tymed := TYMED_ISTREAM;
ZeroMemory(@Medium, SizeOf(Medium));
OleCheck(ADataObject.GetData(Format, Medium));
try
if (Medium.tymed and TYMED_ISTREAM = 0) or not Assigned(Medium.stm) then
InvalidMedium;
Result := IStream(Medium.stm);
finally
ReleaseStgMedium(Medium);
end
end;

procedure WorkWithDropObject(const AFileName: UnicodeString; AStream: IStream);
begin

end;

procedure ProcessDataObject(ADataObject: IDataObject);
var Format: TFormatEtc;
Medium: TStgMedium;
FGDA: PFileGroupDescriptorA;
FGDW: PFileGroupDescriptorW;
i: Integer;
Stream: IStream;
begin
if ContainFormat(ADataObject, CF_FILECONTENTS, TYMED_ISTREAM) then
begin
if ContainFormat(ADataObject, CF_FILEDESCRIPTORW, TYMED_HGLOBAL) then
begin
Format.cfFormat := CF_FILEDESCRIPTORW;
Format.dwAspect := DVASPECT_CONTENT;
Format.lindex := -1;
Format.tymed := TYMED_HGLOBAL;
ZeroMemory(@Medium, SizeOf(Medium));
OleCheck(ADataObject.GetData(Format, Medium));
try
if (Medium.tymed and TYMED_HGLOBAL = 0) or (Medium.hGlobal = 0) then
InvalidMedium;
FGDW := GlobalLock(Medium.hGlobal);
if not Assigned(FGDW) then
RaiseLastOSError;
try
for i := 0 to FGDW.cItems - 1 do
begin
Stream := ExtractStream(ADataObject, i);
try
WorkWithDropObject(FGDW.fgd[i].cFileName, Stream);
finally
Stream := nil;
end;
end;
finally
GlobalUnlock(Medium.hGlobal);
end;
finally
ReleaseStgMedium(Medium);
end
end
else
if ContainFormat(ADataObject, CF_FILEDESCRIPTORA, TYMED_HGLOBAL) then
begin
Format.cfFormat := CF_FILEDESCRIPTORA;
Format.dwAspect := DVASPECT_CONTENT;
Format.lindex := -1;
Format.tymed := TYMED_HGLOBAL;
ZeroMemory(@Medium, SizeOf(Medium));
OleCheck(ADataObject.GetData(Format, Medium));
try
if (Medium.tymed and TYMED_HGLOBAL = 0) or (Medium.hGlobal = 0) then
InvalidMedium;
FGDA := GlobalLock(Medium.hGlobal);
if not Assigned(FGDA) then
RaiseLastOSError;
try
for i := 0 to FGDA.cItems - 1 do
begin
Stream := ExtractStream(ADataObject, i);
try
WorkWithDropObject(FGDA.fgd[i].cFileName, Stream);
finally
Stream := nil;
end;
end;
finally
GlobalUnlock(Medium.hGlobal);
end;
finally
ReleaseStgMedium(Medium);
end
end;
end;
end;

此外,我想创建通用软件,您应该处理以下格式:

  • CF_FILENAMEW/CF_FILENAMEA
  • CF_HDROP
  • CF_IDLIST
  • CF_FILEDESCRIPTORW/CF_FILEDESCRIPTORA/CF_FILECONTENTS

关于delphi - 从 Delphi 中的 IDataObject 检索文件名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21245887/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com