可以将设置变量成功保存到TStream后代。以下是一个例子。
只需创建一个新的vcl表单应用程序,添加两个TButton组件,并在每个按钮的OnClick事件中填写如下示例所示即可。
这是在XE4中创建的,因此对于其他版本的Delphi,uses子句可能不同,但通过在uses子句中删除每个单元之前的名称空间指示器来更改应该是微不足道的。使用Delphi轻松地将带有关节值的集类型变量保存到二进制文件中。换句话说,
还建议查看TypInfo单元(如果您拥有源代码)或仅使用提供的函数,这使得分解Set类型到其文本表示变得相当简单,尽管此处未提供任何示例。如果您想将其保存到配置或ini文件中或以可编辑的持久性格式保存,则建议这样做。
下面这个是我知道的最简单的方法。查看保存到像下面这样的流中的集合类型的二进制输出意味着它基于其大小保存在最小可能的位图表示中。下面的映射到磁盘上的一个字节(值为5),这意味着必须将每个值映射到2的幂(seThis = 1,seThat = 2,seTheOther = 4),就像手动创建的常量位掩码值一样。编译器可能会强制执行它遵循强制使集保留其序数的规则。此示例已在Delphi XE4中进行了测试,运行正常。
希望对您有所帮助。
Brian Joseph Johns
unit Unit1;
interface
uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs,
Vcl.StdCtrls;
type
TSomeEnum = (seThis, seThat, seTheOther);
TSomeEnumSet = set of TSomeEnum;
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
public
end;
var
Form1: TForm1;
SomeSetVar: TSomeEnumSet;
SomeBoolean: Boolean;
SomeInt: Integer;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
SomeSetVar := [seThis, seTheOther];
SomeBoolean := True;
SomeInt := 31415;
with TFileStream.Create('SetSave.bin',fmCreate or fmOpenWrite or fmShareCompat) do
try
Write(SomeSetVar,SizeOf(SomeSetVar));
Write(SomeBoolean,SizeOf(Boolean));
Write(SomeInt,SizeOf(Integer));
finally
Free;
end;
SomeSetVar := [];
SomeInt := 0;
SomeBoolean := False;
end;
procedure TForm1.Button2Click(Sender: TObject);
var
ResponseStr: string;
begin
with TFileStream.Create('SetSave.bin',fmOpenRead or fmShareCompat) do
try
Read(SomeSetVar,SizeOf(SomeSetVar));
Read(SomeBoolean,SizeOf(Boolean));
Read(SomeInt,SizeOf(Integer));
finally
Free;
end;
ResponseStr := 'SomeSetVar = ';
if (seThis in SomeSetVar) then
ResponseStr := ResponseStr + 'seThis ';
if (seThat in SomeSetVar) then
ResponseStr := ResponseStr + 'seThat ';
if (seTheOther in SomeSetVar) then
ResponseStr := ResponseStr + 'seTheOther ';
ResponseStr := ResponseStr + ' SomeBoolean = ' + BoolToStr(SomeBoolean);
ResponseStr := ResponseStr + ' SomeInt = ' + IntToStr(SomeInt);
ShowMessage(ResponseStr);
end;
end.
Classes.pas
中的TReader.ReadSet
和TWriter.WriteProperty
中的WriteSet
。这是VCL将属性与dfm文件流入和流出的方式。如果您使用这些,您需要在数据库中存储一个字符串字段来存储写出的集合。请注意,这种方法会使读取/写入比将值存储在单独的布尔字段中更容易,但使用SQL过滤数据集可能会更困难。 - Marjan VenemaTXSamples = set of TXSample
的类型,然后再声明FXSample: TXSamples
呢?我有点困惑你为什么要在私有字段中这样声明它。最好还是创建另一个类型TXSamples
并将其用于FXSample
... 至少我一直是这样看待并实践的。 - Jerry Dodge