2016-05-11 10 views
2

次のコードは異なるマシンで異なる結果を得ます。 1つのマシンはデスクトップフォルダ(必要ではない)を与え、もう1つはデスクトップフォルダとコンピュータ、割り当てられたドライブ(必要なもの)を与えます。SelectDirectoryには一部のマシンにドライブが含まれていません

procedure TForm1.Button1Click(Sender: TObject); 
var 
    Directory : String; 
begin 
    FileCtrl.SelectDirectory('Caption', 'Desktop', Directory, [sdNewUI, sdShowEdit]); 
end; 

つのマシンは、それが得られます。他のオン

Bad Browse

ことができます:

Good Browse

これは、Windowsの設定のように感じているが、私はどこにわかりません開始。 Delphi XE、Windows 10を使用しています。

ご意見をいただければ幸いです。御時間ありがとうございます。

+1

私の場合は、Vistaで導入されたネイティブのフォルダピッカーである新しい共通ファイル項目ダイアログを使用したい –

+0

ルートデスクトップの名前空間を表示するには、 'Root'パラメータを空の文字列に設定する必要があります(' '')の代わりに ''デスクトップ ''を使います。 –

+0

ありがとう@RemyLebeau! '' Desktop ''の代わりに '' ''を使うと私の問題が解決しました。 – user1627960

答えて

3

回避策
代わりにTFileOpenDialogを使用してください。

  • は常に動作します:
    設定FileOpenDialog1.Options:= [fdoPickFolders,fdoPathMustExist]

    enter image description here

    は今、あなたはそのダイアログを持っています。

  • は、コピーペースト

*)あなただけのフォルダを選択することはできませんTOpenDialog、と混同してはならないことを可能にします。新しいTFileOpenDialogのみVistaおよび上に動作することのWindows XP用

ソリューション
注意。
このコントロールを含めると、プログラムはXPでは動作しません。
XPでダイアログを開始すると、EPlatformVersionExceptionが生成されます。

あなたは下位互換性になりたい場合は代わりに次のコードを使用することもできます。

uses JclSysInfo; //because you have XE use JCL. 

... 
var 
    WinMajorVer: Integer; 
    Directory: string; 
    FileDialog: TFileOpenDialog; 
begin 
    WinMajorVer:= GetWindowsMajorVersionNumber; 
    if WinMajorVer < 6 then begin //pre-vista 
    //To show the root Desktop namespace, you should be setting the Root parameter to an empty string ('') instead of 'Desktop' 
    FileCtrl.SelectDirectory('Caption', '', Directory, [sdNewUI, sdShowEdit]); 
    end else begin 
    FileDialog:= TFileOpenDialog.Create(self); 
    try 
     FileDialog.Options:= [fdoPickFolders,fdoPathMustExist]; 
     if FileDialog.Execute then Directory:= FileOpenDialog1.FileName; 
    finally 
     FileDialog.Free; 
    end; 
    end; 
    Result:= Directory; 
end; 

推奨読書:
detect windows version

EDIT

FileCtrl.SelectDirectory('Caption', 'Desktop', Directory, [sdNewUI, sdShowEdit]); 

'Desktop'に入るそのように扱われるパラメータ、:

pszDisplayName
[中] タイプ:LPWSTR
と、NULLで終了するUnicode文字列

... 
    SHGetDesktopFolder(IDesktopFolder); 
    IDesktopFolder.ParseDisplayName(Application.Handle, nil, 
     Root, Eaten, RootItemIDList, Flags); 
... 

はここIDesktopFolder.ParseDisplayNameのためのMSDNが言っているものです表示名。各シェルフォルダーは独自の解析構文を定義しているため、この文字列で使用できる形式は異なる場合があります。例えば、デスクトップフォルダは "C:\ My Docs \ My File.txt"のようなパスを受け入れます。また、 ":: {GUID}"構文を使用して、名前空間に関連付けられたGUIDを持つ項目への参照も受け入れます。

ドキュメントには、デスクトップフォルダがパスとGUIDを受け入れることが記載されていることに注意してください。それは'Desktop'を受け入れません。それはどちらでもないからです。

'Desktop'rootとして一つのシステム上の作品ではなく、別のIDesktopFolderインタフェースの古い/新しいバージョンで行われたいくつかの文書化されていない修正があるという事実。上記の私のコードに示すように、「ルート」として

技術ソリューション
使用''

明らかにSelectDirectoryは、決して使用されるべきではないMicrosoftの本当に悪いデザインです。それはちょうど非常に多くの方法で吸う。私は可能な限り使用しないことをお勧めします。

+0

* app *は引き続きXPでは動作しますが、*ダイアログ*は実行されません(実行時にダイアログが呼び出されると 'EPlatformVersionException'が発生します)。 –

+0

@RemyLebeau、ありがとうございます。私はテストするXPがないので、何が起こるのか分からなかった。 XPで始まることを考えれば、いくつかの回避コードを追加しました。 – Johan

+0

'if WinVer in ...' - OUCH! Win32MajorVersion <6 then ... 'を使用する方がはるかに簡単です。 'TFileOpenDialog'を解放するために' try/finally'を使います。 –

関連する問題