【问题标题】:Delphi 2007 - Allowing a Read-only file to be selected in a TSaveDialogDelphi 2007 - 允许在 TSaveDialog 中选择只读文件
【发布时间】:2018-01-17 23:05:46
【问题描述】:

我需要用户能够从保存对话框中选择现有的只读文件。我认为您可以通过明智地选择TSaveDialog 选项来做到这一点,但我无法做到这一点。如果我选择一个 R/O 文件,只要我点击Save 按钮,我就会收到消息:

    Read-only.txt
    This file is set to read-only.
    Try again with a different file name.

我以为选项位 ofNoReadOnlyReturn 会控制它,但它似乎没有效果。

我错过了什么?

program Project1;

uses
  Forms,
  Unit1 in 'Unit1.pas' {Form1};

{$R *.res}

begin
  Application.Initialize;
  Application.MainFormOnTaskbar := True;
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.

-

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    SaveDialog1: TSaveDialog;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
if SaveDialog1.Execute then
    begin
    Windows.Beep (1000, 300) ;
    end ;
end ;

end.

-

object Form1: TForm1
  Left = 0
  Top = 0
  Caption = 'Form1'
  ClientHeight = 69
  ClientWidth = 195
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  PixelsPerInch = 96
  TextHeight = 13
  object Button1: TButton
    Left = 56
    Top = 18
    Width = 75
    Height = 25
    Caption = 'Button1'
    TabOrder = 0
    OnClick = Button1Click
  end
  object SaveDialog1: TSaveDialog
    FileName = 'Read-only.txt'
    InitialDir = 'C:\Users\Ross\Documents\RAD Studio\Projects'
    Options = [ofHideReadOnly, ofNoReadOnlyReturn, ofEnableSizing]
    Left = 16
    Top = 16
  end
end

【问题讨论】:

  • 如果文件是只读的,你不能在保存对话框中选择它,因为你不能覆盖文件(它是只读的)。如果您希望用户能够覆盖文件,请在显示对话框之前先删除 readonly 属性。(当您知道您希望用户能够时,首先将文件设为只读几乎没有意义覆盖它。我将此文件设为只读以防止用户覆盖它。等等,我如何让用户覆盖文件?)
  • 目的是重置 R/O 标志,允许覆盖,然后再次设置 R/O 标志。问题是这些文件被标记为只读,因为我们想防止“一般”用户覆盖它们,但这些文件偶尔需要由主管更新(使用只有他们有权访问的程序),我想这样做过程尽可能无痛。
  • 稍微玩一下表明 TOpenDialog 允许选择只读文件,而 TSaveDialog 不允许(不管您在选项中使用的标志)。显然,VCL 包装器中的某些东西干扰了使用 TSaveDialog 选择只读文件的能力。不知道这是否会有所帮助,但是......也不确定你是否知道,所以我会提到它:你可以在设计时通过在 OI 中设置你想要的选项来试验对话框,然后双击该组件,这将打开包含当前选项的对话框。它使测试非常快。
  • 谢谢肯。不,我不知道双击的设计时预览 - 非常有用,特别是如果项目需要一段时间来构建和启动。最终,我确实使用了TOpenDialog,并在OnShow 事件中使用代码来弯曲Open 按钮标题以读取Save
  • 是的,设计时预览甚至允许测试文件掩码和初始目录以及其他东西,而不仅仅是选项设置。不是每个人都知道,我想我会提到它。这是一个非常有用的功能,适用于所有对话框组件(TSaveDialog、TFileSaveDialog 等)。

标签: delphi delphi-2007 readonly-attribute tsavedialog


【解决方案1】:

问题不在于TSaveDialog 本身,而在于TSaveDialog 在内部使用的底层Win32 GetSaveFileName()/IFileSaveDialog API。他们根本不允许只读/只读文件成为“保存”对话框的结果。

话虽如此,IFileSaveDialog 确实提供了一个可能(虽然丑陋)的解决方法。如果启用对话框的FOS_OVERWRITEPROMPT 标志,则选择现有文件将提示用户是否可以在关闭对话框之前覆盖该文件。 IFileDialogEvents 接口有一个OnOverwrite 事件,在该提示出现之前触发(并且可以返回FDESVR_ACCEPT 以完全跳过该提示)。因此,在这种情况下,您可以在关闭对话框之前删除文件的 FILE_ATTRIBUTE_READONLY 属性。但是,对话框仍然会显示相同的“此文件设置为只读”错误消息并拒绝关闭(可能是因为它在触发OnOverwrite 事件之前检查了属性),但如果您随后选择相同的文件再次,属性将被清除,对话框将接受文件(这是丑陋的部分 - 您必须训练您的经理忽略该错误并重试)。

GetSaveFileName() 有一个ofOverwritePrompt 标志,但没有用于覆盖提示的事件。

话虽如此,TSaveDialog 在内部使用IFileSaveDialog 时不会公开对IFileSaveDialog.OnOverwrite 事件的访问权限,但您可以改用TFileSaveDialog,这样做。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-22
    • 1970-01-01
    • 2016-02-25
    • 2017-12-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多