Umgehung
Verwenden Sie einen TFileOpenDialog
statt *.
Set FileOpenDialog1.Options:= [fdoPickFolders,fdoPathMustExist]
Jetzt haben Sie einen Dialog, dass:
- funktioniert immer.
- Ermöglicht Kopieren und Einfügen
*) Nicht mit dem TOpenDialog verwechselt werden, die Sie ermöglicht nicht nur auf Ordner auswählen.
Lösung für Windows XP
Beachten Sie, dass die neue TFileOpenDialog nur für Vista arbeitet und darüber.
Ihr Programm wird nicht auf XP funktionieren, wenn Sie dieses Steuerelement einschließen.
Wenn Sie den Dialog unter XP starten, wird ein EPlatformVersionException
generiert.
Sie wollen stattdessen den folgenden Code verwenden, wenn Sie rückwärts sein wollen kompatibel:
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;
Empfohlene Lektüre:
detect windows version
EDIT
FileCtrl.SelectDirectory('Caption', 'Desktop', Directory, [sdNewUI, sdShowEdit]);
Die 'Desktop'
geht in die Root
Parameter, die wie so gehandhabt wird:
...
SHGetDesktopFolder(IDesktopFolder);
IDesktopFolder.ParseDisplayName(Application.Handle, nil,
Root, Eaten, RootItemIDList, Flags);
...
Hier ist, was MSDN für IDesktopFolder.ParseDisplayName zu sagen hat:
pszDisplayName [in]
Typ: LPWSTR
Ein nullterminierten Unicode-String mit der Anzeigename. Da jeder Shell-Ordner seine eigene Syntax zum Parsen definiert, kann die Form, die diese Zeichenfolge annehmen kann, variieren. Der Desktop-Ordner akzeptiert beispielsweise Pfade wie "C: \ My Docs \ My File.txt". Es akzeptiert auch Verweise auf Elemente im Namespace, denen eine GUID mit der Syntax ":: {GUID}" zugeordnet ist.
Beachten Sie, dass in der Dokumentation angegeben wird, dass der Desktop-Ordner Pfade und Leitfäden akzeptiert. Es akzeptiert keine 'Desktop'
. Weil das auch nicht ist.
Die Tatsache, dass 'Desktop'
als root
auf einem System aber nicht anderen funktioniert, ist einige nicht dokumentierte behoben in einer älteren/neueren Version der IDesktopFolder
Schnittstelle gemacht.
Technische Lösung
Verwenden ''
als 'root', wie oben in meinem Code gezeigt.
Offensichtlich SelectDirectory
ist ein wirklich schlechtes Design von Microsoft, das nie verwendet werden sollte. Es saugt einfach auf so viele Arten. Ich empfehle es nicht verwendet werden, wann immer es möglich ist.
Wenn ich es wäre, würde ich den neuen allgemeinen Dateieingabedialog verwenden, der in Vista eingeführt wurde, der die native Ordnerauswahl ist –
Um den root Desktop Namespace anzuzeigen, sollten Sie den 'Root' Parameter auf eine leere Zeichenfolge setzen ") anstelle von" Desktop ". –
Danke @RemyLebeau! '' '' Anstelle von ''Desktop'' löste mein Problem. – user1627960