(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?
-
23-09-2019 - |
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 ...
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
.