(حفظ مربع الحوار) كيفية تغيير تمديد الملف تلقائيًا في تغيير ملف تصفية الملف في Vista/Win7؟
-
23-09-2019 - |
سؤال
أثناء عرض مربع حوار حفظ ، أريد ربط نوع مرشح المستخدم وتغيير تمديد الملف تلقائيًا. (على سبيل المثال ، مثل عملية "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
منشأه.