2014-09-03 37 views
0

我正在使用來自Angus Johnson的TDropPIDLTarget組件& Anders Melander的拖放組件套件允許用戶通過將附件拖放到表單中來添加附件。我遇到的問題是確定文件是來自虛擬位置(即:相機驅動器還是iPhone驅動器)還是來自常規文件系統。這是我使用的驗證的概念代碼:確定文件是否位於Delphi 2007中的ItemIDList的虛擬位置

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

甚至文件系統的項目可以是虛擬的。 – 2014-09-03 18:02:55

回答

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; 
+0

再次感謝您的幫助!我發現整件事情都沒有實際意義,不過因爲我可以將GetDisplayNameOf選項更改爲「SHGDN_NORMAL或SHGN_FORPARSING或SHGDN_FORADDRESSBAR」,我將顯示正確的文件名,而不管它是否位於虛擬位置。我沒有意識到我需要釋放StrRet對象,所以非常感謝。 – Caynadian 2014-09-03 18:51:37

相關問題