(Diálogo Guardar) Cómo cambiar la extensión de archivo de forma automática en el cambio de filtro de archivos en Vista / Win7?

StackOverflow https://stackoverflow.com/questions/2145299

Pregunta

Mientras que muestra un cuadro de diálogo Guardar, quiero enganchar el cambio de tipo de filtro y el archivo de cambiar la extensión del usuario de forma automática. (Por ejemplo, como la operación "Guardar como" de MSPaint.)

Con TSaveDialog y UseLatestCommonDialogs de ajuste: = False, Puedo manejar esto mediante el siguiente código. (Sin soporte más reciente de diálogo común, de 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;

Quiero apoyar tanto XP y Vista / 7 con Delphi 2007.

¿Debo usar TFileSaveDialog en lugar de TSaveDialog con la envoltura interna? (Y tengo que lucha con la programación COM utilizando IFileDialogControlEvents ?)

o puedo lograr esto con TFileSaveDialog y es solamente propiedades estándar? (Mi entorno de desarrollo está todavía en la máquina XP, así que nunca he intentado. Lo siento.)

Creo que es tarea muy común, pero no pude encontrar ningún código de ejemplo apoyando Vista / 7 ...

¿Fue útil?

Solución

Por lo que yo sé, TFileSaveDialog lanzará una excepción en XP. Se necesita Vista o arriba.

Actualizar algunos código D2010 TFileSaveDialog adaptado de su controlador de eventos ....
(No tengo D2007 en Vista, el uso PWideChar en lugar de PChar)

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;

Cuando el FileSaveDialog es:

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

Otros consejos

Usted escribió que no se podía cortar la envoltura. Yo uso este código para mi XLSX / XLS / SAO exportadores biblioteca para cambiar la extensión del archivo tanto en XP y Vista +.

Uno de los inconvenientes: ayudantes de clase no pueden acceder a los campos privados en Delphi 2007, por lo que este código funciona sólo en Delphi 2009+. Si quieres Delphi compatibilidad 2007, utilizar el mismo truco para TOpenDialog como antes para TFileDialogWrapper en este ejemplo.

{ 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;

Editar : en realidad, si se establece la propiedad DefaultExt, cuidado de Delphi / Windows sobre el cambio de extensión de archivo para usted. En ese caso, usted no tiene que hacer nada en caso OnTypeChange.

Esta característica se implementa en Delphi, pero desactivado por defecto.

Para activarlo, la entrada sólo la extensión por defecto en la propiedad DefaultExt.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top