我正在使用Angus Johnson& Co.的TDropPIDLTarget组件。 Anders Melander的拖放组件套件允许用户通过将附件拖入表单来添加附件。我遇到的问题是确定文件是来自虚拟位置(即:摄像头驱动器还是iPhone驱动器)还是来自常规文件系统。这是我正在使用的概念验证代码:
procedure TfrmForm.dftFileDropDrop(Sender: TObject; ShiftState: TShiftState;
Point: TPoint; var Effect: Integer);
Var
I: Integer;
pItem: PItemIDList;
Desktop: IShellFolder;
FileName: TStrRet;
Attr: UINT;
begin
If FAILED(SHGetDesktopFolder(Desktop)) Then
Exit;
For I := 1 To dftFileDrop.PidlCount - 1 Do
Begin
pItem := dftFileDrop.GetAbsoluteFilePidl(I);
Attr := SFGAO_FileSystem;
If Succeeded(Desktop.GetAttributesOf(1, pItem, Attr)) Then
Begin
If (Attr Or SFGAO_FILESYSTEM) = Attr Then
Desktop.GetDisplayNameOf(pItem, SHGDN_NORMAL Or SHGDN_FORPARSING, Filename)
Else
Desktop.GetDisplayNameOf(pItem, SHGDN_NORMAL Or SHGDN_FORADDRESSBAR, Filename);
mResults.Lines.Add(Filename.pOleStr);
End;
End;
end;
SFGAO_FileSystem常量应该表示:
"指定的文件夹或文件是文件系统的一部分(即, 它们是文件,目录或根目录)。已解析的名称 可以假定这些项是有效的Win32文件系统路径。这些 路径可以是UNC或基于驱动器号。"
这听起来像我想要使用但我似乎无法从GetAttributesOf获得正确的结果。我这样做是正确的吗?
答案 0 :(得分:2)
您需要使用And
运算符,而不是Or
运算符:
If (Attr and SFGAO_FILESYSTEM) <> 0 Then
您还需要在访问pOleStr
之前检查失败(并且您不应该假设该值总是在pOleStr
中,因为它可能并非总是如此)。
完成使用后,您还需要释放STRRET
内容。最好的方法是使用StrRetTo...()
函数之一,它将为您处理,并为您分析STRRET.uType
字段,以便它知道在何处以及如何提取字符串数据。
尝试更像这样的事情:
procedure TfrmForm.dftFileDropDrop(Sender: TObject; ShiftState: TShiftState;
Point: TPoint; var Effect: Integer);
var
I: Integer;
pItem: PItemIDList;
Desktop: IShellFolder;
FileName: TStrRet;
Attr: UINT;
hr: HRESULT;
szFileName: array[0..MAX_PATH] of Char;
begin
If FAILED(SHGetDesktopFolder(Desktop)) Then
Exit;
For I := 1 To dftFileDrop.PidlCount - 1 Do
Begin
pItem := dftFileDrop.GetAbsoluteFilePidl(I);
If Succeeded(Desktop.GetAttributesOf(1, pItem, Attr)) Then
Begin
If (Attr And SFGAO_FILESYSTEM) <> 0 Then
hr := Desktop.GetDisplayNameOf(pItem, SHGDN_NORMAL Or SHGDN_FORPARSING, Filename)
Else
hr := Desktop.GetDisplayNameOf(pItem, SHGDN_NORMAL Or SHGDN_FORADDRESSBAR, Filename);
If Succeeded(hr) then
Begin
if Succeeded(StrRetToBuf(@Filename, pItem, szFileName, MAX_PATH)) then
mResults.Lines.Add(szFileName);
End;
End;
End;
End;