(حفظ مربع الحوار) كيفية تغيير تمديد الملف تلقائيًا في تغيير ملف تصفية الملف في Vista/Win7؟

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

سؤال

أثناء عرض مربع حوار حفظ ، أريد ربط نوع مرشح المستخدم وتغيير تمديد الملف تلقائيًا. (على سبيل المثال ، مثل عملية "Save As" لـ Mspaint.)

مع 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 ، و Vista/7 مع Delphi 2007.

هل يجب أن أستخدم tfilesavedialog بدلاً من tsavedialog مع غلاف داخلي؟ (ويجب أن أتعامل مع برمجة COM باستخدام IfileDialogControlevents ?)

أو هل يمكنني تحقيق ذلك باستخدام tfilesavedialog وهي خصائص قياسية فقط؟ (لا تزال بيئة التطوير الخاصة بي على آلة XP ، لذلك لم أحاول أبدًا. آسف.)

أعتقد أنها مهمة شائعة جدًا ، لكنني لم أتمكن من العثور على أي رمز عينة يدعم Vista/7 ...

هل كانت مفيدة؟

المحلول

على حد علمي ، فإن Tfilesavedialog سوف يثير استثناء على XP. يحتاج إلى فيستا أو فوق.

تحديث: بعض رمز D2010 ل tfilesavedialog مقتبس من معالج الحدث الخاص بك ....
(ليس لدي D2007 على Vista ؛ استخدم Pwidechar بدلاً من 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;

حيث يكون 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

نصائح أخرى

لقد كتبت أنه لا يمكنك اختراق الغلاف. يمكنني استخدام هذا الرمز لمكتبة تصدير XLSX/XLS/ODS لتغيير امتداد الملف على كل من XP و Vista+.

عيب واحد: لا يمكن للمساعدين في الفصل الوصول إلى الحقول الخاصة في Delphi 2007 ، لذلك يعمل هذا الرمز فقط في Delphi 2009+. إذا كنت تريد توافق Delphi 2007 ، فاستخدم نفس الاختراق لـ Topendialog كما استخدمت لـ TfileDialogWrapper في هذا المثال.

{ 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 خاصية ، Delphi/Windows تهتم بتغيير ملحق الملف بالنسبة لك. في هذه الحالة ، لا يتعين عليك فعل أي شيء في OnTypeChange حدث.

يتم تنفيذ هذه الميزة في Delphi ، ولكن معطل بشكل افتراضي.

من أجل تنشيطه ، ما عليك سوى إدخال الامتداد الافتراضي في DefaultExt منشأه.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top