Je viens de trouver le code ci-dessous qui semble fonctionner correctement sous XP et Vista, Win7. Il fournit une interface utilisateur permettant à un utilisateur de sélectionner un répertoire. Il utilise TOpenDialog, mais lui envoie quelques messages pour nettoyer l'apparence dans le but de sélectionner un répertoire.
Après avoir souffert des capacités limitées offertes par Windows lui-même, c'est un plaisir de pouvoir offrir à mes utilisateurs une interface utilisateur familière où ils peuvent parcourir et sélectionner une liste de produits. dossier confortablement.
Cela faisait longtemps que je cherchais quelque chose comme ça, alors j'ai pensé le poster ici pour que d'autres puissent en profiter.
Voici à quoi cela ressemble dans Win 7 :
//***********************
//** Choose a directory **
//** uses Messages **
//***********************
//General usage here:
// http://www.delphipages.com/forum/showthread.php?p=185734
//Need a class to hold a procedure to be called by Dialog.OnShow:
type TOpenDir = class(TObject)
public
Dialog: TOpenDialog;
procedure HideControls(Sender: TObject);
end;
//This procedure hides de combo box of file types...
procedure TOpenDir.HideControls(Sender: TObject);
const
//CDM_HIDECONTROL and CDM_SETCONTROLTEXT values from:
// doc.ddart.net/msdn/header/include/commdlg.h.html
// CMD_HIDECONTROL = CMD_FIRST + 5 = (WM_USER + 100) + 5;
//Usage of CDM_HIDECONTROL and CDM_SETCONTROLTEXT here:
// msdn.microsoft.com/en-us/library/ms646853%28VS.85%29.aspx
// msdn.microsoft.com/en-us/library/ms646855%28VS.85%29.aspx
CDM_HIDECONTROL = WM_USER + 100 + 5;
CDM_SETCONTROLTEXT = WM_USER + 100 + 4;
//Component IDs from:
// msdn.microsoft.com/en-us/library/ms646960%28VS.85%29.aspx#_win32_Open_and_Save_As_Dialog_Box_Customization
//Translation into exadecimal in dlgs.h:
// www.koders.com/c/fidCD2C946367FEE401460B8A91A3DB62F7D9CE3244.aspx
//
//File type filter...
cmb1: integer = $470; //Combo box with list of file type filters
stc2: integer = $441; //Label of the file type
//File name const...
cmb13: integer = $47c; //Combo box with name of the current file
edt1: integer = $480; //Edit with the name of the current file
stc3: integer = $442; //Label of the file name combo
var H: THandle;
begin
H:= GetParent(Dialog.Handle);
//Hide file types combo...
SendMessage(H, CDM_HIDECONTROL, cmb1, 0);
SendMessage(H, CDM_HIDECONTROL, stc2, 0);
//Hide file name label, edit and combo...
SendMessage(H, CDM_HIDECONTROL, cmb13, 0);
SendMessage(H, CDM_HIDECONTROL, edt1, 0);
SendMessage(H, CDM_HIDECONTROL, stc3, 0);
//NOTE: How to change label text (the lentgh is not auto):
//SendMessage(H, CDM_SETCONTROLTEXT, stc3, DWORD(pChar('Hello!')));
end;
//Call it when you need the user to chose a folder for you...
function GimmeDir(var Dir: string): boolean;
var
OpenDialog: TOpenDialog;
OpenDir: TOpenDir;
begin
//The standard dialog...
OpenDialog:= TOpenDialog.Create(nil);
//Objetc that holds the OnShow code to hide controls
OpenDir:= TOpenDir.create;
try
//Conect both components...
OpenDir.Dialog:= OpenDialog;
OpenDialog.OnShow:= OpenDir.HideControls;
//Configure it so only folders are shown (and file without extension!)...
OpenDialog.FileName:= '*.';
OpenDialog.Filter:= '*.';
OpenDialog.Title:= 'Chose a folder';
//No need to check file existis!
OpenDialog.Options:= OpenDialog.Options + [ofNoValidate];
//Initial folder...
OpenDialog.InitialDir:= Dir;
//Ask user...
if OpenDialog.Execute then begin
Dir:= ExtractFilePath(OpenDialog.FileName);
result:= true;
end else begin
result:= false;
end;
finally
//Clean up...
OpenDir.Free;
OpenDialog.Free;
end;
end;
0 votes
SelectDirectory utilise le dialogue de sélection de répertoire natif du système. Vous semblez vouloir utiliser quelque chose d'autre, mais vous ne dites pas ce qui est faible dans SelectDirectory, et vous ne dites pas quelles fonctionnalités vous recherchez dans le remplacement.
0 votes
David : Ce n'est pas si simple. Le site
FileCtrl.SelectDirectory
a deux implémentations surchargées. L'une d'entre elles produit une boîte de dialogue de style Windows 3.1, tandis que l'autre produit une boîte de dialogue native.0 votes
@Andreas alors la réponse est sûrement d'utiliser la bonne surcharge. Voulez-vous écrire cette réponse ? Ha, vous l'avez déjà fait !
7 votes
@peter Je pense que votre meilleure option est TFileOpenDialog avec fdoPickFolders sur Vista+ et la version SHBrowseForFolder de SelectDirectory sur XP et inférieur.
3 votes
Ce dont vous avez besoin, c'est d'implémenter votre propre recherche de dossier à l'aide d'un formulaire et d'un cerveau.
13 votes
N'implémentez pas votre propre code de recherche de dossiers. Impossible d'assurer l'avenir et très difficile à réaliser correctement.
2 votes
@David Je pense que FindFirst et FindNext sont très évolutifs.
0 votes
@opc0de Cette API est garantie de ne jamais s'étendre sur l'espace de nom du shell maintenant ou dans le futur !
0 votes
@David, @opc0de : Je suis tout à fait d'accord avec David. Il est bien mieux d'utiliser les boîtes de dialogue natives du système d'exploitation. Personnellement, j'utilise toujours la fonction
TFileOpenDialog
sur Vista+ et de se replier en utilisant le (bon !)SelectDirectory
sur XP.1 votes
Méthode rapide et sale que j'ai vue dans divers logiciels gratuits pour Windows : utiliser la boîte de dialogue d'enregistrement et ignorer le nom de fichier du résultat. Sur
SelectDirectory
: il s'agit simplement d'une enveloppe pour la fonctionSHBrowseForFolder
Cependant, il n'utilise pas tous les avantages offerts par les shells modernes (y compris le contrôle d'édition - BIF_EDITBOX {v 4.71}). Je suggère d'utiliser cette fonction directement à la place, ou de réutiliser un wrapper prêt à l'emploi.0 votes
+1 En étudiant SHBrowseForFolder, il est étonnant de voir à quel point il est flexible. C'est ce qui ressort de la création d'un wrapper VCL pour cette application. Je n'ai jamais compris l'intérêt de TOpenDialog pour la sélection de répertoire, étant donné ce que l'on peut faire avec SHBrowseForFolder.