代码之家  ›  专栏  ›  技术社区  ›  Jan Goyvaerts

使他逐渐使用最新的公共对话框

  •  1
  • Jan Goyvaerts  · 技术社区  · 16 年前

    在Delphi2007及以后的版本中,全局变量 UseLatestCommonDialogs 原因 TOpenDialog 在Windows Vista和7上使用“新建Vista样式”对话框。那太酷了。

    不幸的是,vista样式对话框似乎不支持 ofHideReadOnly topendialog选项。无论此选项设置为true还是false,都不会显示只读复选框。

    如何使topendialog在vista样式对话框中显示只读复选框?

    由于这破坏了向后兼容性,我将其报告为一个错误: QC 83606 当使用Delphi2007、2009或2010编译时,若Delphi2006应用程序的默认值设置为false,则在WindowsVista或7上运行的Delphi2006应用程序将丢失其只读复选框。

    1 回复  |  直到 16 年前
        1
  •  1
  •   Jan Goyvaerts    16 年前

    我在Delphi2010中通过如下修改dialogs.pas实现了这一点:

    首先,声明并实现类 TFileOpenDialogWrapperReadOnlyEvent :

    { TFileOpenDialogWrapperReadOnlyEvent }
    
    type
      TFileOpenDialogWrapperReadOnlyEvent = class(TInterfacedObject, IFileDialogEvents, IFileDialogControlEvents)
      private
        FOpenDialog: TOpenDialog;
      public
        function OnButtonClicked(const pfdc: IFileDialogCustomize; dwIDCtl: Cardinal): HRESULT; stdcall;
        function OnCheckButtonToggled(const pfdc: IFileDialogCustomize; dwIDCtl: Cardinal; bChecked: LongBool): HRESULT; stdcall;
        function OnControlActivating(const pfdc: IFileDialogCustomize; dwIDCtl: Cardinal): HRESULT; stdcall;
        function OnItemSelected(const pfdc: IFileDialogCustomize; dwIDCtl: Cardinal; dwIDItem: Cardinal): HRESULT; stdcall;
        function OnFileOk(const pfd: IFileDialog): HRESULT; stdcall;
        function OnFolderChange(const pfd: IFileDialog): HRESULT; stdcall;
        function OnFolderChanging(const pfd: IFileDialog; const psiFolder: IShellItem): HRESULT; stdcall;
        function OnOverwrite(const pfd: IFileDialog; const psi: IShellItem; out pResponse: Cardinal): HRESULT; stdcall;
        function OnSelectionChange(const pfd: IFileDialog): HRESULT; stdcall;
        function OnShareViolation(const pfd: IFileDialog; const psi: IShellItem; out pResponse: Cardinal): HRESULT; stdcall;
        function OnTypeChange(const pfd: IFileDialog): HRESULT; stdcall;
      end;
    
    function TFileOpenDialogWrapperReadOnlyEvent.OnButtonClicked(const pfdc: IFileDialogCustomize; dwIDCtl: Cardinal): HRESULT;
    begin
      Result := S_OK
    end;
    
    function TFileOpenDialogWrapperReadOnlyEvent.OnCheckButtonToggled(const pfdc: IFileDialogCustomize; dwIDCtl: Cardinal; bChecked: LongBool): HRESULT;
    begin
      if bChecked then FOpenDialog.Options := FOpenDialog.Options + [ofReadOnly]
        else FOpenDialog.Options := FOpenDialog.Options - [ofReadOnly];
      Result := S_OK
    end;
    
    function TFileOpenDialogWrapperReadOnlyEvent.OnControlActivating(const pfdc: IFileDialogCustomize; dwIDCtl: Cardinal): HRESULT;
    begin
      Result := S_OK
    end;
    
    function TFileOpenDialogWrapperReadOnlyEvent.OnFileOk(const pfd: IFileDialog): HRESULT;
    begin
      Result := S_OK
    end;
    
    function TFileOpenDialogWrapperReadOnlyEvent.OnFolderChange(const pfd: IFileDialog): HRESULT;
    begin
      Result := S_OK
    end;
    
    function TFileOpenDialogWrapperReadOnlyEvent.OnFolderChanging(const pfd: IFileDialog; const psiFolder: IShellItem): HRESULT;
    begin
      Result := S_OK
    end;
    
    function TFileOpenDialogWrapperReadOnlyEvent.OnItemSelected(const pfdc: IFileDialogCustomize; dwIDCtl, dwIDItem: Cardinal): HRESULT;
    begin
      Result := S_OK
    end;
    
    function TFileOpenDialogWrapperReadOnlyEvent.OnOverwrite(const pfd: IFileDialog; const psi: IShellItem; out pResponse: Cardinal): HRESULT;
    begin
      Result := S_OK
    end;
    
    function TFileOpenDialogWrapperReadOnlyEvent.OnSelectionChange(const pfd: IFileDialog): HRESULT;
    begin
      Result := S_OK
    end;
    
    function TFileOpenDialogWrapperReadOnlyEvent.OnShareViolation(const pfd: IFileDialog; const psi: IShellItem; out pResponse: Cardinal): HRESULT;
    begin
      Result := S_OK
    end;
    
    function TFileOpenDialogWrapperReadOnlyEvent.OnTypeChange(const pfd: IFileDialog): HRESULT;
    begin
      Result := S_OK
    end;
    

    将此字符串声明为资源,以便可以对其进行本地化(如果您关心此问题):

    resourcestring
      SReadOnly = 'Read only';
    

    然后修改 TFileOpenDialogWrapper.OnExecuteEvent 分两步走。首先,添加以下变量声明:

    C: IFileDialogCustomize;
    E: TFileOpenDialogWrapperReadOnlyEvent;
    Cookie: Cardinal;
    

    然后在过程结束时添加此代码:

    if not (ofHideReadOnly in FOpenDialog.Options) then begin
      if FFileDialog.Dialog.QueryInterface(IFileDialogCustomize, C) = S_OK then begin
        C.AddCheckButton(1, PChar(SReadOnly), ofReadOnly in FOpenDialog.Options);
        E := TFileOpenDialogWrapperReadOnlyEvent.Create;
        E.FOpenDialog := FOpenDialog;
        FFileDialog.Dialog.Advise(E, Cookie);
      end;
    end;
    

    将新的dialogs.pas复制到源代码文件夹中,并删除或重命名delphi中的两个dialogs.dcu文件 Lib 文件夹。重新编译你的应用程序,他只会使用vista风格的对话框。