सवाल TOpenDialog के साथ एक निर्देशिका का चयन


मैं वास्तव में विभिन्न तरीकों से जानना चाहता हूं कि मैं TOpenDialog के साथ एक निर्देशिका का चयन कर सकता हूं, चाहे वह एक नया घटक डाउनलोड कर रहा हो या डेल्फी द्वारा प्रदान की जाने वाली चीज़ों का उपयोग कर, लेकिन अधिमानतः डेल्फी द्वारा प्रदान की जाने वाली चीज़ों का उपयोग करना।

इससे पहले, मैं SelectDirectory कमांड का उपयोग कर रहा हूं लेकिन मुझे लगता है कि यह मेरे प्रोग्राम के उपयोगकर्ताओं को निर्दिष्ट निर्देशिका को देखने में कठिनाई होगी।

मुझे लगता है कि SelectDirectory 'कमजोर' है क्योंकि आप जिस निर्देशिका को चाहते हैं उसकी खोज करते समय यह एक लंबी प्रक्रिया हो सकती है। उदाहरण के लिए कहें, आप एप्लिकेशन डेटा निर्देशिका में नेविगेट करना चाहते हैं। वहां नेविगेट करना कितना लंबा या मुश्किल होगा? अंत में, उपयोगकर्ता अपनी वांछित निर्देशिका तक भी नहीं पहुंच सकते हैं।

मुझे ऐसा कुछ चाहिए जहां उपयोगकर्ता शीर्ष पर निर्देशिका पता बार में निर्देशिका कॉपी और पेस्ट कर सकता है।

enter image description here

आपके सभी उत्तरों के लिए धन्यवाद।


44
2017-09-14 20:38


मूल


@ पीटर मुझे लगता है कि आपका सबसे अच्छा विकल्प TFileOpenDialog है जो Vista + पर fdoPickFolders और XP और डाउन पर SelectDirectory के SHBrowseForFolder संस्करण के साथ है। - David Heffernan
आपको एक फॉर्म और कुछ मस्तिष्क का उपयोग करके फ़ोल्डर के लिए अपना खुद का ब्राउज़ लागू करना है - opc0de
फ़ोल्डर कोड के लिए अपना खुद का ब्राउज़ लागू न करें। भविष्य के सबूत के लिए असंभव और अच्छी तरह से करने के लिए बहुत मुश्किल है। - David Heffernan
@ डेविड मुझे लगता है कि FindFirst और FindNext बहुत भविष्य के सबूत हैं। - opc0de
विभिन्न मुक्त विंडोज सॉफ़्टवेयर में मैंने देखा है त्वरित और गंदे तरीके: संवाद सहेजें का उपयोग करें और परिणाम के फ़ाइल नाम को अनदेखा करें। पर SelectDirectoryसमारोह: यह केवल एक रैपर है SHBrowseForFolderहालांकि, यह आधुनिक शैल प्रदान करने वाले सभी फायदों का उपयोग नहीं करता है (इसमें संपादन नियंत्रण - BIF_EDITBOX {v 4.71} शामिल है)। मैं इसके बजाय सीधे इस फ़ंक्शन का उपयोग करने का सुझाव देता हूं, या किसी के तैयार किए गए आवरण का पुन: उपयोग करता हूं। - Premature Optimization


जवाब:


आप इसका उपयोग कर सकते हैं TFileOpenDialog (Vista + पर):

with TFileOpenDialog.Create(nil) do
  try
    Options := [fdoPickFolders];
    if Execute then
      ShowMessage(FileName);
  finally
    Free;
  end;

व्यक्तिगत रूप से, मैं हमेशा उपयोग करता हूं TFileOpenDialog Vista + पर और फॉलबैक का उपयोग कर SelectDirectory (अच्छा एक!) एक्सपी पर, इस तरह:

if Win32MajorVersion >= 6 then
  with TFileOpenDialog.Create(nil) do
    try
      Title := 'Select Directory';
      Options := [fdoPickFolders, fdoPathMustExist, fdoForceFileSystem]; // YMMV
      OkButtonLabel := 'Select';
      DefaultFolder := FDir;
      FileName := FDir;
      if Execute then
        ShowMessage(FileName);
    finally
      Free;
    end
else
  if SelectDirectory('Select Directory', ExtractFileDrive(FDir), FDir,
             [sdNewUI, sdNewFolder]) then
    ShowMessage(FDir)

62
2017-09-14 20:45



नहीं, मैं विंडोज संस्करण पर ऐसी शाखाओं को नापसंद करता हूं। साथ ही, विलय करें, इस एकल प्रदर्शन में ओपी द्वारा अनुरोध किए गए विभिन्न तरीकों की कमी है। - Premature Optimization
TFileOpenDialog! = TOpenDialog ... TOpenDialog में ऐसा कोई विकल्प नहीं है और TFileOpenDialog FireMonkey में मौजूद नहीं है - Flash Thunder


आप जानते हैं कि दो अधिभारित कार्यों को बुलाया जाता है FileCtrl.SelectDirectory पूरी तरह से अलग संवाद पैदा करता है, है ना?

SelectDirectory(s, [], 0);

स्क्रीनशॉट http://privat.rejbrand.se/oldseldir.png

SelectDirectory('Select a directory', s, s, []);

स्क्रीनशॉट http://privat.rejbrand.se/newseldir.png


53
2017-09-14 21:02



"Välf mapp" निश्चित रूप से "निर्देशिका का चयन करें" +1 धड़कता है - David Heffernan
@ डेविड: ठीक है, इसे संवाद की 'सहजता' का सबूत मानें! - Andreas Rejbrand
वास्तव में आपको अपने दो उत्तरों को एक साथ जोड़ना चाहिए और Vista + और XP के बीच व्यवहार स्विच के बारे में कुछ चर्चा करना चाहिए। - David Heffernan
आप जानते हैं, मैं वास्तव में नहीं जानता था कि इस प्रो के दो संस्करण थे। मैंने शायद ही कभी इसका इस्तेमाल किया है - लेकिन महाकाव्य है कि मुझे खोल के साथ नृत्य नहीं करना पड़ा - धन्यवाद! - Jon Lennart Aasenden
मुझे लगता है कि आप इसका उपयोग नहीं कर सकते हैं s रूट पैरामीटर और निर्देशिका पैरामीटर के लिए चर (दूसरा और तीसरा पैरामीटर SelectDirectory('Select a directory', s, s, []);) - manlio


बस नीचे दिया गया कोड जो XP और Vista, Win7 में ठीक काम करता प्रतीत होता है। यह किसी उपयोगकर्ता को निर्देशिका चुनने के लिए यूआई प्रदान करता है। यह TOpenDialog का उपयोग करता है, लेकिन निर्देशिका को चुनने के प्रयोजनों के लिए उपस्थिति को साफ करने के लिए इसे कुछ संदेश भेजता है।

विंडोज़ द्वारा उपलब्ध सीमित क्षमताओं से पीड़ित होने के बाद, यह मेरे उपयोगकर्ताओं को एक परिचित यूआई देने में सक्षम होने का आनंद है जहां वे ब्राउज़ कर सकते हैं और चुन सकते हैं फ़ोल्डर आराम से।

मैं इस तरह से कुछ समय के लिए खोज रहा था इसलिए सोचा कि मैं इसे यहां पोस्ट करूंगा ताकि अन्य इससे लाभ उठा सकें।

Win 7 में यह कैसा दिखता है:

screen capture

//***********************
//** 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;

6
2017-09-05 13:58



मुझे यह पसंद है, लेकिन यह कष्टप्रद है कि आपको अंतिम चरण में फ़ोल्डर को दो बार चुनना होगा। और आप पेड़ में अंतिम निर्देशिका को छोड़कर कुछ भी नहीं चुन सकते हैं। - Aaron


बस शामिल करें

FileCtrl.pas

var
  sDir:String;
begin
  SelectDirectory('Your caption','',sDir);
end;

डेस्कटॉप सहित सभी निर्देशिकाओं को देखना चाहते हैं तो बस दूसरा तर्क खाली छोड़ दें। यदि आप किसी भी वैध पथ पर दूसरा तर्क सेट करते हैं, तो आपके संवाद में शीर्ष फ़ोल्डर का वह पथ होगा और आप इससे आगे नेविगेट नहीं कर सकते हैं।

उदाहरण के लिए:

SelectDirectory('Your caption','C:\',sDir) आपको कुछ भी आगे नहीं चुनने देगा C:\, पसंद D:\ या E:\  आदि।

तो इसे खाली छोड़ना अच्छा है।


6
2017-11-28 19:44





यदि आप उपयोग कर रहे हैं JVCL आप TJvSelectDirectory का उपयोग कर सकते हैं। इसके साथ आप संपत्ति सेट करके पुरानी और नई शैली के बीच स्विच कर सकते हैं। उदाहरण के लिए:

Dlg := TJvSelectDirectory.Create(Self);
try
    Dlg.Title := MyTitle;
    Dlg.InitialDir := MyStartDir;
    Dlg.Options := Dlg.Options + [sdAllowCreate, sdPerformCreate];     
    Dlg.ClassicDialog := False;   //switch style
    if Dlg.Execute() then
      NewDir := Dlg.Directory;
finally
    Dlg.Free;
end; 

2
2017-07-17 07:59