2010-01-27 1 views
8

저장 대화 상자가 표시되는 동안 사용자의 필터 유형 변경을 연결하고 파일 확장명을 자동으로 변경하려고합니다. (예 : MSPaint의 '다른 이름으로 저장'작업)(저장 대화 상자) Vista/Win7에서 파일 필터 변경시 파일 확장자를 자동으로 변경하는 방법은 무엇입니까?

TSaveDialog를 사용하고 UseLatestCommonDialogs : = False로 설정하면 다음 코드로 처리 할 수 ​​있습니다. (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를 지원하고자, 델파이 2007과/7

내가 대신 TSaveDialog의 TFileSaveDialog 내부 래퍼와 함께 사용해야 비스타? (그리고 IFileDialogControlEvents을 사용하여 COM 프로그래밍에 어려움을 겪고 있습니까?)

또는 TFileSaveDialog로이를 수행 할 수 있습니까? (내 개발 환경은 XP 시스템에 아직, 그래서 나는 한 번도 안 써봤. 죄송합니다.)

나는 그것이 매우 일반적인 일이라고 생각하지만 비스타/7 ...

를 지원하는 모든 샘플 코드를 찾을 수 없습니다

답변

5

내가 아는 한 TFileSaveDialog는 XP에서 예외를 발생시킵니다. Vista가 필요합니다.

업데이트 : 이벤트 핸들러에서 적응 TFileSaveDialog에 대한 몇 가지 D2010 코드는 ....
(I 비스타에 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

고마워요! 하지만 대개 런타임에 이러한 대화 상자를 작성하므로 OS 버전 확인을 통해 TSaveDialog와 TFileSaveDialog를 모두 전환 할 수 있습니다. – benok

+0

D2007과 호환됩니다. PChar/string-> PWideChar/WideString을 변경합니다 (D2009 이상에서 자동 형식 변환이 가능할 수 있습니다). 감사! p.s. Parent.ClassName = 'TFileSaveDialogWrapper'와 같이 "* SaveDialog1 * TypeChange"내부를 전환하려고했습니다.(대화 상자 클래스를 바꾸는 것보다 더 손쉬운 방법입니다.)하지만 구현 섹션에서 정의 된대로 래퍼를 해킹 할 수는 없습니다 ... – benok

4

당신은 당신이 해킹 수 없다는 것을 썼다 래퍼. XLSX/XLS/ODS 익스포트 라이브러리에이 코드를 사용하여 XP 및 Vista +에서 파일 확장명을 변경합니다.

단점 : 클래스 도우미는 Delphi 2007에서 비공개 필드에 액세스 할 수 없으므로이 코드는 Delphi 2009 이상에서만 작동합니다. Delphi 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

사실, 지금 확인했습니다 - Dialogs 유닛 아키텍처 때문에 Delphi XE +에서만 작동합니다. – oxo

+0

답변 해 주셔서 감사합니다. 나는 방금 알아 챘다. 더 이상 D2007을 사용하지 않고 코드를 읽습니다. 감사. – benok

0

이 기능은 Delphi에서 구현되지만 기본적으로 비활성화되어 있습니다.

활성화하려면 DefaultExt 속성의 기본 확장명을 입력하십시오.

관련 문제