2010-01-27 21 views
8

एक सहेजने वाला संवाद दिखाते समय, मैं उपयोगकर्ता के फ़िल्टर प्रकार परिवर्तन को हुक करना और फ़ाइल एक्सटेंशन को स्वचालित रूप से बदलना चाहता हूं। (उदाहरण के लिए एमएसपीएन्ट की "सेव एज़" ऑपरेशन की तरह।)(सहेजें संवाद) Vista/Win7 में फ़ाइल फ़िल्टर परिवर्तन पर फ़ाइल एक्सटेंशन को स्वचालित रूप से कैसे बदलें?

TSaveDialog के साथ और UseLatestCommonDialogs को सेट करना: = गलत, मैं इसे निम्नलिखित कोड से संभाल सकता हूं। (Cource के नवीनतम आम संवाद समर्थन, बिना।)

procedure TForm1.SaveDialog1TypeChange(Sender: TObject); 
var 
    FName, Ext: string; 
begin 
    with TSaveDialog(Sender) do 
    begin 
    if DirectoryExists(FileName) then // FileName is Empty 
     exit; 
    case FilterIndex of 
    1: Ext := '.png'; 
    2: Ext := '.bmp'; 
    3: Ext := '.jpg'; 
    end; 
    FName := ChangeFileExt(ExtractFileName(FileName), Ext); 
    SendMessage(Windows.GetParent(Handle), CDM_SETCONTROLTEXT, 1152, LongInt(PChar(FName))); 
    end; 
end; 

मैं दोनों XP समर्थन करना चाहते हैं, और विस्टा/7 डेल्फी 2007 के साथ

मैं आंतरिक आवरण के साथ TSaveDialog के बजाय TFileSaveDialog उपयोग करना चाहिए? (और मुझे IFileDialogControlEvents का उपयोग कर COM प्रोग्रामिंग के साथ संघर्ष करना है?)

या क्या मैं इसे TFileSaveDialog और केवल मानक गुणों के साथ प्राप्त कर सकता हूं? (मेरे विकास के वातावरण अभी भी XP मशीन पर खेद है, इसलिए मैं कभी नहीं की कोशिश की है।।)

मुझे लगता है कि यह बहुत ही सामान्य कार्य है, लेकिन मैं Vista/7 ...

समर्थन किसी भी नमूना कोड नहीं मिल सका

उत्तर

5

जहां तक ​​मुझे पता है, TFileSaveDialog XP पर अपवाद उठाएगा। इसे Vista या ऊपर की आवश्यकता है।

अद्यतन: TFileSaveDialog के लिए कुछ D2010 कोड अपने ईवेंट हैंडलर से अनुकूलित ....
(मैं Vista पर D2007 नहीं है; PChar के बजाय PWideChar का उपयोग)

procedure TForm1.FileSaveDialog1TypeChange(Sender: TObject); 
var 
    FName, Ext: string; 
    pName: PChar; 
begin 
    with TFileSaveDialog(Sender) do 
    begin 
    if DirectoryExists(FileName) then // FileName is Empty 
     exit; 
    case FileTypeIndex of 
    1: Ext := '.png'; 
    2: Ext := '.bmp'; 
    3: Ext := '.jpg'; 
    end; 
    Dialog.GetFileName(pName); 
    FName := ChangeFileExt(ExtractFileName(pName), Ext); 
    Dialog.SetFileName(PChar(FName)); 
    end; 
end; 

कहाँ FileSaveDialog है:

object FileSaveDialog1: TFileSaveDialog 
    FavoriteLinks = <> 
    FileTypes = < 
    item 
     DisplayName = 'png files' 
     FileMask = '*.png' 
    end 
    item 
     DisplayName = 'bmp files' 
     FileMask = '*.bmp' 
    end 
    item 
     DisplayName = 'jpg files' 
     FileMask = '*.jpg' 
    end> 
    Options = [] 
    OnTypeChange = FileSaveDialog1TypeChange 
end 
+0

धन्यवाद! लेकिन मैं आमतौर पर रनटाइम में इन संवादों को बना देता हूं, इसलिए मैं ओएस संस्करण जांच के साथ दोनों TSaveDialog और TFileSaveDialog को स्विच कर सकता हूं। – benok

+0

यह डी 2007 के साथ काम करता है। मैं बस पीसीहर/स्ट्रिंग-> PWideChar/वाइडस्ट्रिंग को बदलता हूं। (यह डी 2009 या बाद में ऑटो टाइप रूपांतरण के साथ काम करता है।)। धन्यवाद! पी। मैंने "* SaveDialog1 * TypeChange" के अंदर स्विच करने की कोशिश की, "अगर Parent.ClassName = 'TFileSaveDialogWrapper'" का उपयोग कर।(यह संवाद वर्गों को स्विच करने से आसान है।) लेकिन मैं रैपर को हैक नहीं कर सका, क्योंकि इसे कार्यान्वयन अनुभाग में परिभाषित किया गया है ... – benok

4

आप ने लिखा है कि आप हैक नहीं कर सका आवरण। मैं अपने एक्सएलएसएक्स/एक्सएलएस/ओडीएस निर्यात पुस्तकालय के लिए इस कोड का उपयोग XP और Vista + दोनों पर फ़ाइल एक्सटेंशन को बदलने के लिए करता हूं।

एक दोष: कक्षा सहायक डेल्फी 2007 में निजी क्षेत्रों तक नहीं पहुंच सकते हैं, इसलिए यह कोड केवल डेल्फी 200+ में काम करता है। यदि आप डेल्फी 2007 संगतता चाहते हैं, तो इस उदाहरण में TFileDialogWrapper के लिए उपयोग किए जाने वाले TOpenDialog के लिए एक ही हैक का उपयोग करें।

{ interface } 

    //some hacking needed to change the file extension at type change, 
    //empty class is just fine... 
    TFileDialogWrapper = class(TObject) 
    private 
    {$HINTS OFF} 
    procedure AssignFileTypes; 
    procedure AssignOptions; 
    function GetFileName: TFileName; 
    function GetHandle: HWND; 
    procedure HandleShareViolation(Sender: TObject; 
     var Response: TFileDialogShareViolationResponse); 
    procedure OnFileOkEvent(Sender: TObject; var CanClose: Boolean); 
    procedure OnFolderChangeEvent(Sender: TObject); 
    procedure OnSelectionChangeEvent(Sender: TObject); 
    procedure OnTypeChangeEvent(Sender: TObject); 
    protected 
    FFileDialog: TCustomFileDialog; 
    {$HINTS ON} 
    end; 
    TOpenDialogHelper = class helper for TOpenDialog 
    public 
    function GetInternalWrapper: TFileDialogWrapper; 
    end; 

{ implementation } 

{ TOpenDialogHelper } 

function TOpenDialogHelper.GetInternalWrapper: TFileDialogWrapper; 
begin 
    Result := TFileDialogWrapper(Self.FInternalWrapper); 
end; 

{ TFileDialogWrapper } 

procedure TFileDialogWrapper.AssignFileTypes; 
begin 
end; 

procedure TFileDialogWrapper.AssignOptions; 
begin 
end; 

function TFileDialogWrapper.GetFileName: TFileName; 
begin 
end; 

function TFileDialogWrapper.GetHandle: HWND; 
begin 
end; 

procedure TFileDialogWrapper.HandleShareViolation(Sender: TObject; 
    var Response: TFileDialogShareViolationResponse); 
begin 
end; 

procedure TFileDialogWrapper.OnFileOkEvent(Sender: TObject; 
    var CanClose: Boolean); 
begin 
end; 

procedure TFileDialogWrapper.OnFolderChangeEvent(Sender: TObject); 
begin 
end; 

procedure TFileDialogWrapper.OnSelectionChangeEvent(Sender: TObject); 
begin 
end; 

procedure TFileDialogWrapper.OnTypeChangeEvent(Sender: TObject); 
begin 
end; 

//use this for OnTypeChane event of a "normal" TOpenDialog/TSaveDialog 

procedure TForm1.DialogTypeChange(Sender: TObject); 
var 
    xFN: WideString; 
    xExporter: TOCustomExporter; 
    xFileName: PWideChar; 
    xFD: TFileDialogWrapper; 
    xFilterIndex: UINT; 
begin 
    if Sender is TOpenDialog then 
    with TOpenDialog(Sender) do begin 
    xFD := GetInternalWrapper; 
    if (xFD <> nil) and (xFD.FFileDialog <> nil) 
    then begin 
     //Vista file dialog 

     xFD.FFileDialog.Dialog.GetFileName(xFileName); 
     if xFileName = '' then 
     exit; 
     xFN := xFileName; 
     xFD.FFileDialog.Dialog.GetFileTypeIndex(xFilterIndex); 

     // DO WHATEVER YOU WANT WITH THE FILENAME HERE // 

     xFD.FFileDialog.Dialog.SetFileName(PWideChar(xFN)); 
    end else begin 
     //Old dialog 
     xFN := ExtractFileName(FileName); 
     if xFN = '' then 
     exit; 

     // DO WHATEVER YOU WANT WITH THE FILENAME HERE // 

     {$HINTS OFF} 
     SendMessage(Windows.GetParent(Handle), CDM_SETCONTROLTEXT, 1152, LongInt(PWideChar(xFN))); 
     {$HINTS ON} 
    end; 
    end; 
end; 

संपादित: वास्तव में, यदि आप DefaultExt गुण सेट, डेल्फी/विंडोज आप के लिए फाइल एक्सटेंशन परिवर्तन के बारे में परवाह है। उस स्थिति में आपको OnTypeChange ईवेंट में कुछ भी करने की ज़रूरत नहीं है।

+0

असल में, मैंने इसे अभी चेक किया - यह डायलॉग यूनिट आर्किटेक्चर की वजह से केवल डेल्फी एक्सई + में काम करता है। – oxo

+0

आपके उत्तर के लिए धन्यवाद। मैंने अभी देखा है। मैं अब डी 2007 का उपयोग नहीं कर रहा हूं, मैं आपका कोड पढ़ूंगा। धन्यवाद। – benok

0

यह सुविधा डेल्फी में लागू की गई है, लेकिन डिफ़ॉल्ट रूप से अक्षम है।

इसे सक्रिय करने के लिए, बस DefaultExt संपत्ति में डिफ़ॉल्ट एक्सटेंशन दर्ज करें।