(Dialogue Enregistrer) Comment changer l'extension du fichier automatiquement sur le changement de filtre de fichiers dans Vista / Windows 7?

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

Question

Tout en montrant une boîte de dialogue Enregistrer, je veux accrocher le changement de type de filtre de l'utilisateur et l'extension de fichier change automatiquement. (Par exemple, comme l'opération "Enregistrer sous" de MSPaint.)

Avec TSaveDialog et réglage UseLatestCommonDialogs: = False, Je peux gérer cela par le code suivant. (Sans le dernier support de dialogue commun, 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;

Je veux soutenir à la fois XP et Vista / 7 avec Delphi 2007.

Dois-je utiliser TFileSaveDialog au lieu de TSaveDialog avec emballage interne? (Et je dois lutter avec la programmation COM en utilisant IFileDialogControlEvents ?)

Ou puis-je parvenir avec TFileSaveDialog et ses propriétés standard uniquement? (Mon environnement de développement est encore sur la machine XP, donc je ne l'ai jamais essayé. Excusez-moi.)

Je pense qu'il est très tâche commune, mais je ne pouvais pas trouver un exemple de code supportant Vista / 7 ...

Était-ce utile?

La solution

Pour autant que je sache, TFileSaveDialog déclenche une exception sur XP. Il a besoin de Vista ou vers le haut.

Mise à jour : certains Code D2010 TFileSaveDialog adapté à partir de votre gestionnaire d'événements ....
(Je n'ai pas D2007 sur Vista, utilisez PWideChar au lieu 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;

Si le FileSaveDialog est:

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

Autres conseils

Vous avez écrit que vous ne pouviez pas pirater l'emballage. J'utilise ce code pour ma bibliothèque XLSX / XLS / ODS exportation pour changer l'extension du fichier sur XP et Vista +.

Un inconvénient: les aides de classe ne peuvent pas accéder aux champs privés Delphi 2007, de sorte que ce code ne fonctionne que dans Delphi 2009+. Si vous voulez Delphi 2007 compatibilité, utilisez la même astuce pour TOpenDialog comme je l'ai utilisé pour TFileDialogWrapper dans cet exemple.

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

EDIT : En fait, si vous définissez la propriété DefaultExt, Delphi / Windows soins au sujet du changement d'extension de fichier pour vous. Dans ce cas, vous ne devez pas faire quoi que ce soit en cas de OnTypeChange.

Cette fonctionnalité est implémentée dans Delphi, mais désactivé par défaut.

Pour l'activer, l'entrée juste l'extension par défaut dans la propriété DefaultExt.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top