TFileOpenDialog和TFileSaveDialog具有不同的GUID

时间:2015-09-23 16:55:25

标签: delphi delphi-10-seattle

我创建了后代TFileOpenDialog和TFileSaveDialog。 GUID是否相同或不同?我在TFileOpen和TFileSave对话框中使用了它:

FileDialog.QueryInterface(StringToGUID('{8016B7B3-3D49-4504-A0AA-2A37494E606F}'), FileDialogCustomize);

我创建了两个演示来测试组件。一个运行时间和另一个设计时间。

我询问GUID,因为当我在运行时创建TFileOpenDialog后代时,TFileOpenDialog会显示标题为' Open File'并且预览显示在对话框的右侧。它是完美的,并且可以按照您的预期运行,但是当我安装对话框并运行设计时演示时,会出现一个标题为' Save File'并且没有显示预览。

我不明白为什么会发生这种情况。如果有必要,我可以显示一些代码,但我不明白为什么设计时间和运行时间会有不同的表现,因为对话框的创建方式不同:

//TFileOpenDialog descendent
CoCreateInstance(CLSID_FileOpenDialog, nil, CLSCTX_INPROC_SERVER,
    IFileOpenDialog, FileDialog);
//TFileSaveDialog descendent
CoCreateInstance(CLSID_FileSaveDialog, nil, CLSCTX_INPROC_SERVER,
    IFileSaveDialog, FileDialog);

这是开放式对话代码:

{ TIEWin7FileOpenDialog }

constructor TIEWin7FileOpenDialog.Create(AOwner: TComponent);
begin
  FillOpenFileTypesFilter;
  inherited Create(AOwner);
end;

destructor TIEWin7FileOpenDialog.Destroy;
begin
  inherited Destroy;
end;

procedure TIEWin7FileOpenDialog.FillOpenFileTypesFilter;
{ Fill the TIEWin7FileOpenDialog FFilterArray with FileTypes }
begin
  CoCreateInstance(CLSID_FileOpenDialog, nil, CLSCTX_INPROC_SERVER,
    IFileOpenDialog, FileDialog);
  { Create an array of file types for OpenDialog }
  SetLength(FFilterArray, 26);
  FFilterArray[0].pszName := PWideChar(Widestring('Common Graphic Files'));
  FFilterArray[0].pszSpec :=
    PWideChar(Widestring
    ('*.tif;*.tiff;*.gif;*.png;*.apf;*.cur;*.pcx;*.ani;*.jpg;*.jpeg;*.jp2;*.j2k*;*.bmp;*.ico;*.emf;*.wmf;*.tga;*.wdp;*.hdp;*.avi')
    );
  FFilterArray[1].pszName := PWideChar(Widestring('JPEG Bitmap'));
  FFilterArray[1].pszSpec := PWideChar(Widestring('*.jpg;*.jpeg;*.jpe;*.jif'));
  FFilterArray[2].pszName := PWideChar(Widestring('TIFF Bitmap'));
  FFilterArray[2].pszSpec :=
    PWideChar(Widestring('*.tif;*.tiff;*.fax;*.g3n;*.g3f;*.xif'));
  FFilterArray[3].pszName := PWideChar(Widestring('CompuServe Bitmap'));
  FFilterArray[3].pszSpec := PWideChar(Widestring('*.gif'));
  FFilterArray[4].pszName := PWideChar(Widestring('PaintBrush'));
  FFilterArray[4].pszSpec := PWideChar(Widestring('*.pcx'));
  FFilterArray[5].pszName := PWideChar(Widestring('Windows Bitmap'));
  FFilterArray[5].pszSpec := PWideChar(Widestring('*.bmp;*.dib;*.rle'));
  FFilterArray[6].pszName := PWideChar(Widestring('Windows Icon'));
  FFilterArray[6].pszSpec := PWideChar(Widestring('*.ico'));
  FFilterArray[7].pszName := PWideChar(Widestring('Windows Cursor'));
  FFilterArray[7].pszSpec := PWideChar(Widestring('*.cur'));
  FFilterArray[8].pszName := PWideChar(Widestring('Portable Network Graphics'));
  FFilterArray[8].pszSpec := PWideChar(Widestring('*.png'));
  FFilterArray[9].pszName := PWideChar(Widestring('DICOM Bitmap'));
  FFilterArray[9].pszSpec := PWideChar(Widestring('*.dcm;*.dic;*.dicom;*.v2'));
  FFilterArray[10].pszName := PWideChar(Widestring('Windows Metafile'));
  FFilterArray[10].pszSpec := PWideChar(Widestring('*.wmf'));
  FFilterArray[11].pszName := PWideChar(Widestring('Targa Bitmap'));
  FFilterArray[11].pszSpec :=
    PWideChar(Widestring('*.tga;*.targa;*.vda;*.icb;*.vst;*.pix'));
  FFilterArray[12].pszName :=
    PWideChar(Widestring('Portable Pixmap, GrayMap, BitMap'));
  FFilterArray[12].pszSpec := PWideChar(Widestring('*.pxm;*.ppm;*.pgm;*.pbm'));
  FFilterArray[13].pszName := PWideChar(Widestring('Wireless Bitmap'));
  FFilterArray[13].pszSpec := PWideChar(Widestring('*.wbmp'));
  FFilterArray[14].pszName := PWideChar(Widestring('JPEG2000'));
  FFilterArray[14].pszSpec := PWideChar(Widestring('*.jp2'));
  FFilterArray[15].pszName := PWideChar(Widestring('JPEG2000 Code Stream'));
  FFilterArray[15].pszSpec := PWideChar(Widestring('*.j2k;*.jpc;*.j2c'));
  FFilterArray[16].pszName := PWideChar(Widestring('Multipage PCX'));
  FFilterArray[16].pszSpec := PWideChar(Widestring('*.dcx'));
  FFilterArray[17].pszName := PWideChar(Widestring('Camera RAW'));
  FFilterArray[17].pszSpec :=
    PWideChar(Widestring
    ('*.crw;*.cr2;*.nef;*.raw;*.pef;*.raf;*.x3f;*.bay;*.orf;*.srf;*.mrw;*.dcr;*.sr2')
    );
  FFilterArray[18].pszName := PWideChar(Widestring('Photoshop PSD'));
  FFilterArray[18].pszSpec := PWideChar(Widestring('*.psd'));
  FFilterArray[19].pszName :=
    PWideChar(Widestring('ImageEn Vectorial Objects'));
  FFilterArray[19].pszSpec := PWideChar(Widestring('*.iev'));
  FFilterArray[20].pszName := PWideChar(Widestring('ImageEn Layers'));
  FFilterArray[20].pszSpec := PWideChar(Widestring('*.lyr'));
  FFilterArray[21].pszName :=
    PWideChar(Widestring('ImageEn Layers and Objects'));
  FFilterArray[21].pszSpec := PWideChar(Widestring('*.all'));
  FFilterArray[22].pszName := PWideChar(Widestring('Microsoft HD Photo'));
  FFilterArray[22].pszSpec := PWideChar(Widestring('*.wdp;*.hdp'));
  FFilterArray[23].pszName := PWideChar(Widestring('Video For Windows'));
  FFilterArray[23].pszSpec := PWideChar(Widestring('*.avi'));
  FFilterArray[24].pszName := PWideChar(Widestring('Mpeg'));
  FFilterArray[24].pszSpec := PWideChar(Widestring('*.mpeg;*.mpg'));
  FFilterArray[25].pszName := PWideChar(Widestring('Windows Media Video'));
  FFilterArray[25].pszSpec := PWideChar(Widestring('*.wmv'));
  { Set the FileTypes Filter Array }
  FilterArray := FFilterArray;
end;

function TIEWin7FileOpenDialog.DoExecute: BOOL;
{ Create the dialogs and add control items }
const
  dwVisualGroup1ID: DWORD = 1200;
  dwVisualGroup2ID: DWORD = 1300;
  dwVisualGroup3ID: DWORD = 1400;
  dwVisualGroup4ID: DWORD = 1500;
  dwVisualGroup5ID: DWORD = 1600;
  dwVisualGroup6ID: DWORD = 1700;
  dwVisualGroup7ID: DWORD = 1800;
var
  iFileDialogEvent: TFileDialogEvent;
  iCookie: cardinal;
  iWideString: Widestring;
  iFilename: PWideChar;
  iFileTypeIndex: Integer;
  hr: HResult;
  ShellItem: IShellItem;
  iOptionsSet: cardinal;
begin
  { Add labels }
  FileDialog.QueryInterface(IFileDialogCustomize, FileDialogCustomize);
  FileDialogCustomize.StartVisualGroup(dwVisualGroup1ID, 'Frames');
  FileDialogCustomize.AddControlItem(1, 0, 'Frames: ');
  FileDialogCustomize.AddText(1, '');
  FileDialogCustomize.EndVisualGroup;
  { Add a visual group for BitDepth }
  FileDialogCustomize.StartVisualGroup(dwVisualGroup2ID, 'BitDepth');
  FileDialogCustomize.AddControlItem(2, 1, 'BitDepth: ');
  FileDialogCustomize.AddText(2, '');
  FileDialogCustomize.EndVisualGroup;
  { Add a visual group for Dimensions }
  FileDialogCustomize.StartVisualGroup(dwVisualGroup3ID, 'Dimensions');
  FileDialogCustomize.AddControlItem(3, 2, 'Dimensions:');
  FileDialogCustomize.AddText(3, '');
  FileDialogCustomize.EndVisualGroup;
  { Add a visual group for DPI }
  FileDialogCustomize.StartVisualGroup(dwVisualGroup4ID, 'DPI');
  FileDialogCustomize.AddControlItem(4, 3, 'DPI:');
  FileDialogCustomize.AddText(4, '');
  FileDialogCustomize.EndVisualGroup;
  { Add a visual group for FileType }
  FileDialogCustomize.StartVisualGroup(dwVisualGroup5ID, 'File Type');
  FileDialogCustomize.AddControlItem(5, 4, 'File Type:');
  FileDialogCustomize.AddText(5, '');
  FileDialogCustomize.EndVisualGroup;
  { Add a visual group for FileSize }
  FileDialogCustomize.StartVisualGroup(dwVisualGroup6ID, 'File Size');
  FileDialogCustomize.AddControlItem(6, 5, 'File Type:');
  FileDialogCustomize.AddText(6, '');
  FileDialogCustomize.EndVisualGroup;
  { Add a visual group for MemorySize }
  FileDialogCustomize.StartVisualGroup(dwVisualGroup7ID, 'Memory Size');
  FileDialogCustomize.AddControlItem(7, 6, 'Memory:');
  FileDialogCustomize.AddText(7, '');
  FileDialogCustomize.EndVisualGroup;
  { Set Default Extension }
  iWideString := self.DefaultExtension;
  FileDialog.SetDefaultExtension(PWideChar(iWideString));
  { Set Default Filename }
  iWideString := FileName;
  iFilename := PWideChar(FileName);
  FileDialog.SetFilename(iFilename);
  { Set FileType (filter) index }
  iFileTypeIndex := 1;
  FileDialog.SetFileTypeIndex(iFileTypeIndex);
  self.FileTypeIndex := iFileTypeIndex;
  { Set Options }
  iOptionsSet := 0;
  if fdoOverwritePrompt in Options then
    iOptionsSet := iOptionsSet + FOS_OVERWRITEPROMPT;
  if fdoStrictFileTypes in Options then
    iOptionsSet := iOptionsSet + FOS_STRICTFILETYPES;
  if fdoNoChangeDir in Options then
    iOptionsSet := iOptionsSet + FOS_NOCHANGEDIR;
  if fdoPickFolders in Options then
    iOptionsSet := iOptionsSet + FOS_PICKFOLDERS;
  if fdoForceFileSystem in Options then
    iOptionsSet := iOptionsSet + FOS_FORCEFILESYSTEM;
  if fdoAllNonStorageItems in Options then
    iOptionsSet := iOptionsSet + FOS_ALLNONSTORAGEITEMS;
  if fdoNoValidate in Options then
    iOptionsSet := iOptionsSet + FOS_NOVALIDATE;
  if fdoAllowMultiSelect in Options then
    iOptionsSet := iOptionsSet + FOS_ALLOWMULTISELECT;
  if fdoPathMustExist in Options then
    iOptionsSet := iOptionsSet + FOS_PATHMUSTEXIST;
  if fdoFileMustExist in Options then
    iOptionsSet := iOptionsSet + FOS_FILEMUSTEXIST;
  if fdoCreatePrompt in Options then
    iOptionsSet := iOptionsSet + FOS_CREATEPROMPT;
  if fdoShareAware in Options then
    iOptionsSet := iOptionsSet + FOS_SHAREAWARE;
  if fdoNoReadOnlyReturn in Options then
    iOptionsSet := iOptionsSet + FOS_NOREADONLYRETURN;
  if fdoNoTestFileCreate in Options then
    iOptionsSet := iOptionsSet + FOS_NOTESTFILECREATE;
  if fdoHideMRUPlaces in Options then
    iOptionsSet := iOptionsSet + FOS_HIDEMRUPLACES;
  if fdoHidePinnedPlaces in Options then
    iOptionsSet := iOptionsSet + FOS_HIDEPINNEDPLACES;
  if fdoNoDereferenceLinks in Options then
  iOptionsSet := iOptionsSet + FOS_NODEREFERENCELINKS;
  if fdoDontAddToRecent in Options then
    iOptionsSet := iOptionsSet + FOS_DONTADDTORECENT;
  if fdoForceShowHidden in Options then
    iOptionsSet := iOptionsSet + FOS_FORCESHOWHIDDEN;
  if fdoDefaultNoMiniMode in Options then
    iOptionsSet := iOptionsSet + FOS_DEFAULTNOMINIMODE;
  if fdoForcePreviewPaneOn in Options then
    iOptionsSet := iOptionsSet + FOS_FORCEPREVIEWPANEON;
  FileDialog.SetOptions(iOptionsSet);
  { The array of file types for OpenDialog is initialized in OnCreate }
  { Set the FileTypes }
  FileDialog.SetFileTypes(26, FFilterArray);
  { Setup the TFileDialogEvents }
  iFileDialogEvent := TFileDialogEvent.Create;
  iFileDialogEvent.FType := 'Open';
  iFileDialogEvent.QueryInterface(IFileDialogEvents, FileDialogEvents);
  FileDialog.Advise(iFileDialogEvent, iCookie);
  { Show the dialog }
  hr := FileDialog.Show(Application.Handle);
  if hr = 0 then
  begin
    ShellItem := nil;
    hr := FileDialog.GetResult(ShellItem);
    if hr = 0 then
    begin
      hr := ShellItem.GetDisplayName(SIGDN_FILESYSPATH, iFilename);
      if hr = 0 then
        FileName := iFilename;
    end;
    Result := true;
  end
  else
  begin
    Result := False;
  end;
  FileDialog.Unadvise(iCookie);
end;

function TIEWin7FileOpenDialog.Execute: Boolean;
{ Handle Execute which calls DoExecute before the dialog is visible }
begin
  Result := DoExecute;
end;

procedure TIEWin7FileOpenDialog.OnExecute;
{ Handle Execute which calls DoExecute before the dialog is visible }
begin
  DoExecute;
end;

1 个答案:

答案 0 :(得分:1)

我建议另一种方法 - 从Delphi现有的Vcl.Dialogs.TFileOpenDialog组件派生TIEWin7FileOpenDialog,它为你包装IFileOpenDialog接口。

让构造函数根据需要填充继承的TFileOpenDialog.FileTypes集合,并覆盖虚拟TFileOpenDialog.DoOnExecute()方法以添加可视化组并挂钩IFileDialogControlEvents处理程序。创建DoOnExecute()之后和调用IFileDialog方法之前调用Show()IFileDialog界面将在TFileOpenDialog.Dialog属性中提供。

您的代码手动执行的其他操作已由TFileOpenDialog为您处理。

试试这个:

uses
  ..., Vcl.Dialogs, Winapi.ShlObj;

type
  TIEWin7FileOpenDialog = class(TFileOpenDialog)
  protected
    procedure DoOnExecute; override;
  public
    constructor Create(AOwner: TComponent); override;
  end;

  TIEWin7FileOpenDialogControlEvents = class(TInterfacedObject, IFileDialogEvents, IFileDialogControlEvents)
  public
    // implement IFileDialogControlEvents as needed.
    // TFileOpenDialog already has an IFileDialogEvents
    // implementation so just ignore those methods, though
    // you still have to implement them here...
  end;

constructor TIEWin7FileOpenDialog.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);

  { Fill the FileTypes collection }
  with FileTypes.Add do
  begin
    DisplayName := 'Common Graphic Files';
    FileMask := '*.tif;*.tiff;*.gif;*.png;*.apf;*.cur;*.pcx;*.ani;*.jpg;*.jpeg;*.jp2;*.j2k*;*.bmp;*.ico;*.emf;*.wmf;*.tga;*.wdp;*.hdp;*.avi';
  end;
  with FileTypes.Add do
  begin
    DisplayName := 'JPEG Bitmap';
    FileMask := '*.jpg;*.jpeg;*.jpe;*.jif';
  end;
  // and so on...

  { Set FileType (filter) index }
  FileTypeIndex := 1;
end;

procedure TIEWin7FileOpenDialog.DoOnExecute;
const
  dwVisualGroup1ID: DWORD = 1200;
  dwVisualGroup2ID: DWORD = 1300;
  dwVisualGroup3ID: DWORD = 1400;
  dwVisualGroup4ID: DWORD = 1500;
  dwVisualGroup5ID: DWORD = 1600;
  dwVisualGroup6ID: DWORD = 1700;
  dwVisualGroup7ID: DWORD = 1800;
var
  DialogCustomize: IFileDialogCustomize;
  DialogEvents: TIEWin7FileOpenDialogControlEvents;
  Cookie: Cardinal;
begin
  DialogCustomize := Self.Dialog as IFileDialogCustomize;

  { Add labels }
  DialogCustomize.StartVisualGroup(dwVisualGroup1ID, 'Frames');
  DialogCustomize.AddControlItem(1, 0, 'Frames: ');
  DialogCustomize.AddText(1, '');
  DialogCustomize.EndVisualGroup;
  { Add a visual group for BitDepth }
  DialogCustomize.StartVisualGroup(dwVisualGroup2ID, 'BitDepth');
  DialogCustomize.AddControlItem(2, 1, 'BitDepth: ');
  DialogCustomize.AddText(2, '');
  DialogCustomize.EndVisualGroup;
  { Add a visual group for Dimensions }
  DialogCustomize.StartVisualGroup(dwVisualGroup3ID, 'Dimensions');
  DialogCustomize.AddControlItem(3, 2, 'Dimensions:');
  DialogCustomize.AddText(3, '');
  DialogCustomize.EndVisualGroup;
  { Add a visual group for DPI }
  DialogCustomize.StartVisualGroup(dwVisualGroup4ID, 'DPI');
  DialogCustomize.AddControlItem(4, 3, 'DPI:');
  DialogCustomize.AddText(4, '');
  DialogCustomize.EndVisualGroup;
  { Add a visual group for FileType }
  DialogCustomize.StartVisualGroup(dwVisualGroup5ID, 'File Type');
  DialogCustomize.AddControlItem(5, 4, 'File Type:');
  DialogCustomize.AddText(5, '');
  DialogCustomize.EndVisualGroup;
  { Add a visual group for FileSize }
  DialogCustomize.StartVisualGroup(dwVisualGroup6ID, 'File Size');
  DialogCustomize.AddControlItem(6, 5, 'File Type:');
  DialogCustomize.AddText(6, '');
  DialogCustomize.EndVisualGroup;
  { Add a visual group for MemorySize }
  DialogCustomize.StartVisualGroup(dwVisualGroup7ID, 'Memory Size');
  DialogCustomize.AddControlItem(7, 6, 'Memory:');
  DialogCustomize.AddText(7, '');
  DialogCustomize.EndVisualGroup;

  { Setup the TFileDialogEvents }
  DialogEvents := TIEWin7FileOpenDialogControlEvents.Create;
  DialogEvents.FType := 'Open';
  Self.Dialog.Advise(DialogEvents, Cookie);

  { trigger OnExecute event handler }
  inherited;
end;