目的
写这个程序的目的是生成一个密码和用于快递的名字(生成密码和姓名),并且记下用于哪个电商平台(备注),然后进行保存(导出txt)。为了持续存储,我选择了以不覆盖的方式写入密码和姓名(追加写入)。
效果图
密码生成器类
unit PasswordGenerator;
interface
uses
Windows, SysUtils, Classes, StrUtils;
{TPasswordGenerator 类封装了密码生成的功能}
type
TPasswordGenerator = class
private
FAllowedChars: string; //大小写字母、数字和一系列特殊字符
FPasswordLength: Integer; //密码长度
FGeneratedPasswordsList: TStringList; //用来装生成的密码
function GenerateChar: Char;
public
constructor Create(passwordLength: Integer; allowedChars: string);
procedure GeneratePasswords(count: Integer);
property GeneratedPasswords: TStringList read FGeneratedPasswordsList;
end;
implementation
{构造函数,接受密码长度和允许的字符集作为参数。}
constructor TPasswordGenerator.Create(passwordLength: Integer; allowedChars: string);
begin
inherited Create;
FPasswordLength := passwordLength;
FAllowedChars := allowedChars;
FGeneratedPasswordsList := TStringList.Create;
Randomize; // 初始化随机数生成器
end;
{用于生成一个随机的字符。}
function TPasswordGenerator.GenerateChar: Char;
var
randomIndex: Integer;
begin
randomIndex := Random(Length(FAllowedChars)) + 1;
Result := FAllowedChars[randomIndex];
end;
{生成指定数量的密码,并将它们存储在 FGeneratedPasswordsList 字符串列表中。}
procedure TPasswordGenerator.GeneratePasswords(count: Integer);
var
i, j,n: Integer;
password: string;
begin
FGeneratedPasswordsList.Clear;
for i := 1 to count do
begin
password := '';
for j := 1 to FPasswordLength do
begin
password := password + GenerateChar;
end;
FGeneratedPasswordsList.Add(password);
end;
end;
end.
这段代码定义了一个名为 TPasswordGenerator
的Delphi类,该类封装了生成随机密码的功能。以下是代码逻辑的简要概括及作用:
类定义
- TPasswordGenerator 类是一个用于生成随机密码的类。
- 它有三个私有成员变量:
FAllowedChars
:一个字符串,包含了生成密码时可以使用的字符集(如大小写字母、数字和特殊字符)。FPasswordLength
:一个整数,表示生成的密码的长度。FGeneratedPasswordsList
:一个TStringList
对象,用于存储生成的密码列表。
成员函数
-
构造函数
Create(passwordLength: Integer; allowedChars: string)
:- 接受两个参数:密码长度(
passwordLength
)和允许的字符集(allowedChars
)。 - 初始化
FPasswordLength
和FAllowedChars
成员变量。 - 创建一个新的
TStringList
实例来存储生成的密码,并调用Randomize
来初始化随机数生成器。
- 接受两个参数:密码长度(
-
GenerateChar
函数:- 生成并返回一个随机的字符,该字符来自
FAllowedChars
字符串。 - 使用
Random
函数生成一个随机索引。
- 生成并返回一个随机的字符,该字符来自
-
GeneratePasswords(count: Integer)
过程:- 接受一个整数参数
count
,表示要生成的密码数量。 - 清空
FGeneratedPasswordsList
列表。 - 通过两层循环生成指定数量的密码:外层循环控制生成的密码数量,内层循环根据
FPasswordLength
拼接生成单个密码。 - 每个生成的密码都添加到
FGeneratedPasswordsList
列表中。
- 接受一个整数参数
点击“密码生成”事件
{密码生成}
procedure TForm1.Button1Click(Sender: TObject);
var
i: Integer;
allowedChars: string;
begin
// 根据CheckBox初始化允许的字符集
allowedChars := '';
if chkUpperCase.Checked then
allowedChars := allowedChars + 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
if chkLowerCase.Checked then
allowedChars := allowedChars + 'abcdefghijklmnopqrstuvwxyz';
if chkNumbers.Checked then
allowedChars := allowedChars + '0123456789';
if chkSpecialChars.Checked then
allowedChars := allowedChars + '!@#$%&*+?,';
// 如果用户没有选择任何字符集,则显示错误消息
if allowedChars = '' then
begin
ShowMessage('请选择至少一种字符类型!');
Exit;
end;
passwordGenerator := TPasswordGenerator.Create(StrToInt(Edit2.text),allowedChars); // 创建一个生成8位密码的生成器
passwordGenerator.GeneratePasswords(StrToInt(Edit3.text)); // 生成10个密码
for i := 0 to passwordGenerator.GeneratedPasswords.Count - 1 do
begin
ListBox1.Items[i]:=passwordGenerator.GeneratedPasswords[i];
end;
passwordGenerator.Free; // 不要忘记释放对象
end;
这段代码的逻辑主要集中在一个按钮点击事件处理程序中,用于根据用户的选择生成一系列随机密码,并将这些密码显示在列表框中。以下是详细的逻辑步骤:
-
初始化允许的字符集 (
allowedChars
):- 初始化一个空字符串
allowedChars
,用于存储用户通过复选框(chkUpperCase
,chkLowerCase
,chkNumbers
,chkSpecialChars
)选择的字符类型。 - 遍历这些复选框,如果用户勾选了某个复选框,就将对应的字符集追加到
allowedChars
字符串中。
- 初始化一个空字符串
-
检查字符集是否为空:
- 如果用户没有勾选任何复选框(即
allowedChars
字符串为空),则显示一个错误消息提示用户至少选择一种字符类型,并通过Exit
语句退出当前过程,不再继续执行后续代码。
- 如果用户没有勾选任何复选框(即
-
创建密码生成器对象:
- 使用
TPasswordGenerator.Create
方法创建一个新的TPasswordGenerator
对象实例。这个方法的参数是密码的长度(从Edit2
文本框中获取并转换为整数)和允许的字符集(allowedChars
)。
- 使用
-
生成密码:
- 调用
passwordGenerator
对象的GeneratePasswords
方法,根据用户在Edit3
文本框中输入的数量(转换为整数)生成指定数量的密码。
- 调用
-
将生成的密码添加到列表框中:
- 通过一个循环遍历
passwordGenerator.GeneratedPasswords
字符串列表(该列表包含了所有生成的密码),并将每个密码添加到ListBox1
列表框的相应位置。
- 通过一个循环遍历
-
释放密码生成器对象:
- 最后,通过调用
passwordGenerator.Free
方法释放passwordGenerator
对象所占用的内存资源。这是一个重要的步骤,用于避免内存泄漏。
- 最后,通过调用
总结来说,这段代码通过用户的选择(字符类型和数量)来生成一系列随机密码,并将这些密码显示在界面上的列表框中。
名字生成器类
unit NameGenerator;
interface
uses
SysUtils, Classes;
type
TNameGenerator = class
private
//FNames是从文档中提取出来的名字列表
FNames: TStringList;
procedure InitializeNames(FileName:string);
public
constructor Create(FileName:string);
destructor Destroy; override;
// 公开方法,用于生成随机姓名
function GenerateName:string;
end;
implementation
{ TNameGenerator 姓名生成器类}
constructor TNameGenerator.Create(FileName:string);
begin
inherited Create;
FNames:= TStringList.Create;
InitializeNames(FileName);
Randomize; //在实际应用中,最好将Randomize放在应用程序启动时调用
end;
destructor TNameGenerator.Destroy;
begin
FNames.Free;
inherited Destroy;
end;
{1.txt存储了单字,2.TXT存储了双字,
将文档的名字一个个读取到字符串列表FNamesList中}
procedure TNameGenerator.InitializeNames(FileName:string);
var
Lines: TStringList;
i, j: Integer;
LineText, TempText: string;
begin
// 创建一TStringList 实例
Lines := TStringList.Create;
// 加载文件到 TStringList
Lines.LoadFromFile(FileName);
// 遍历 TStringList 中的每一行
for i := 0 to Lines.Count - 1 do
begin
LineText := Lines[i]; // 获取当前行的文本
// 使用空格分割当前行的文本
TempText := ''; // 用于构建最终的字符串
for j := 1 to Length(LineText) do
begin
if LineText[j] = ' ' then // 如果遇到空格,可以简单处理为每遇到空格就分割
begin
if TempText <> '' then //获得了一个词
begin
FNames.Add(TempText); //将名字放到字符串列表中。方便随机生成取用
TempText := ''; // 重置 TempText
end;
end
else
begin
TempText := TempText + LineText[j]; // 否则,将字符添加到 TempText
end;
end;
// 添加最后一个单词(如果有的话)
if TempText <> '' then
FNames.Add(TempText);
end;
end;
{从名字列表中随机选一定数量的名字出来}
function TNameGenerator.GenerateName:string;
var
NameIndex: Integer;
begin
NameIndex := Random(FNames.Count);
Result:=FNames[NameIndex];
end;
end.
结合下图,辅助理解上面的代码。
这段代码定义了一个名为 TNameGenerator
的类,该类用于从指定的文本文件中读取名字,并将这些名字存储在一个 TStringList
列表中,以便之后可以从中随机选择一个名字。以下是该类的详细概述:
类的成员
-
私有成员:
FNames
:TStringList
类型的私有成员,用于存储从文件中读取的名字。InitializeNames(FileName: string)
: 一个私有过程,用于从指定的文件(FileName
)中读取名字,并将它们添加到FNames
列表中。
-
公共成员:
Create(FileName: string)
: 构造函数,它接收一个文件名作为参数,初始化FNames
列表,并调用InitializeNames
过程来填充该列表。Destroy
: 析构函数,用于释放FNames
列表所占用的内存资源。GenerateName
: 一个公共函数,用于从FNames
列表中随机选择一个名字并返回。
功能概述
-
构造函数 (
Create
):当创建TNameGenerator
类的实例时,构造函数会被调用。它首先创建FNames
列表,然后调用InitializeNames
过程来从指定的文件中读取名字,并将这些名字添加到FNames
列表中。 -
读取名字 (
InitializeNames
):此私有过程负责从提供的文件(FileName
)中读取名字。它首先创建一个临时的TStringList
实例(Lines
),然后使用LoadFromFile
方法加载文件内容。之后,它遍历文件中的每一行,并将每个单词(假设单词由空格分隔)添加到FNames
列表中。如果一行中没有空格,则整行被视为一个名字。 -
生成随机名字 (
GenerateName
):此公共函数使用Random
函数从FNames
列表中随机选择一个索引,并返回该索引对应的名字。
注意点
- 在实际应用中,
Randomize
最好在应用程序启动时只调用一次,而不是在每次创建TNameGenerator
实例时都调用。因为Randomize
使用系统时间作为随机数生成的种子,如果频繁调用,可能会因为时间变化不大而导致生成的随机数序列不够随机。
点击“姓名生成”事件
{姓名生成}
procedure TForm1.Button2Click(Sender: TObject);
var
i: Integer;
FileName, newName: string;
NameGenerator: TNameGenerator;
Names: TStringList;
UniqueNameCount: Integer;
Index: Integer;
begin
// 初始化文件名
FileName := Edit5.Text + '.txt';
// 创建 TNameGenerator 实例(如果它确实需要文件名作为参数)
NameGenerator := TNameGenerator.Create(FileName);
ListBox2.Items.clear;
try
// 创建一个 TStringList 来存储唯一的名字
Names := TStringList.Create;
try
// 尝试生成指定数量的唯一名字(这里假设 Edit6.Text 包含想要的名字数量)
UniqueNameCount := 0;
while UniqueNameCount < StrToInt(Edit6.Text) do
begin
// 生成一个新名字
newName := NameGenerator.GenerateName;
// 使用 IndexOf 方法来检查一个字符串是否已经在 TStringList 中。
Index := Names.IndexOf(newName);
if Index = -1 then
begin
// 如果不在列表中,则添加到列表和 ListBox2
Names.Add(newName);
ListBox2.Items.Add(Edit4.Text + newName); // 假设 Edit4.Text 是前缀
Inc(UniqueNameCount);
end;
// 如果已经在列表中,则循环继续,直到找到一个唯一的名字
end;
finally
// 释放 TStringList 资源
Names.Free;
end;
finally
// 释放 TNameGenerator 资源
NameGenerator.Free;
end;
end;
这段代码的逻辑是为了从一个文本文件中读取名字(这些名字是按行存储的,且文件名由用户通过 Edit5
输入框指定),并生成指定数量的唯一名字(这个数量由用户通过 Edit6
输入框指定)。生成的名字将显示在一个名为 ListBox2
的列表框中,且每个生成的名字前可以添加一个前缀(这个前缀由用户通过 Edit4
输入框指定)。以下是该逻辑的详细步骤:
-
初始化文件名:从
Edit5
输入框获取文件名,并附加.txt
后缀,构成完整的文件名FileName
。 -
创建
TNameGenerator
实例:使用前面获取的文件名FileName
创建一个TNameGenerator
类的实例NameGenerator
。这里假设TNameGenerator
类的构造函数接受一个文件名作为参数,用于从该文件中读取名字。 -
清空
ListBox2
:清除ListBox2
列表框中的所有现有项,以便展示新生成的名字。 -
创建
TStringList
实例:创建一个TStringList
实例Names
,用于存储已经生成并确认唯一的名字。 -
生成唯一名字:
- 进入一个循环,循环次数由
Edit6
输入框中的数值(转换为整数)决定,即生成指定数量的唯一名字。 - 在每次循环中,调用
NameGenerator.GenerateName
方法生成一个新名字newName
。 - 使用
Names.IndexOf(newName)
检查这个新名字是否已经在Names
列表中。如果IndexOf
返回-1
,表示该名字不在列表中,是唯一的。 - 如果名字是唯一的,则将其添加到
Names
列表和ListBox2
列表框中,并在名字前添加由Edit4
输入框指定的前缀。同时,增加UniqueNameCount
计数器的值。 - 如果名字已经在列表中,则不执行任何操作,循环继续,直到生成一个新的唯一名字。
- 进入一个循环,循环次数由
-
资源释放:
- 在
try...finally
块中,确保在退出之前释放Names
字符串列表所占用的资源。 - 在最外层的
finally
块中,确保释放NameGenerator
实例所占用的资源。
- 在
通过这种方式,该代码片段能够确保生成指定数量的唯一名字,并将这些名字(带前缀)展示在 ListBox2
列表框中。
点击“清空”事件
{密码清空}
procedure TForm1.Button4Click(Sender: TObject);
begin
ListBox1.Items.Clear; // 清空ListBox1中的所有项
end;
“导出txt”事件
{导出为txt}
procedure TForm1.Button3Click(Sender: TObject);
var
i: Integer;
sl: TStringList;
FileName: string;
begin
//创建一个保存对话框,以便用户选择文件保存位置
SaveDialog := TSaveDialog.Create(nil);
try
SaveDialog.Title := '保存选中的项到TXT文件';
SaveDialog.Filter := 'Text Files (*.txt)|*.txt|All Files (*.*)|*.*';
if SaveDialog.Execute then
begin
FileName := SaveDialog.FileName; // 获取用户选择的文件名
// 创建一个TStringList来存储要写入文件的项
sl := TStringList.Create;
try
if FileExists(FileName) then
begin
sl.LoadFromFile(FileName); // 加载旧内容
end;
// 遍历ListBox中选中的项
for i := 0 to ListBox1.Items.Count - 1 do
begin
if ListBox1.Selected[i] then // 检查该项是否被选中
begin
sl.Add(ListBox1.Items[i]); // 将选中的项添加到TStringList中
end;
end;
for i := 0 to ListBox2.Items.Count - 1 do
begin
if ListBox2.Selected[i] then // 检查该项是否被选中
begin
sl.Add(ListBox2.Items[i]); // 将选中的项添加到TStringList中
end;
end;
//写入备注
sl.Add(edit1.Text);
//写入分隔符
sl.Add('-------------------------');
// 将TStringList的内容写入到文件中
sl.SaveToFile(FileName);
edit7.Text:=FileName;
ShowMessage('选中的项已成功导出到文件: ' + FileName);
finally
sl.Free; // 释放TStringList实例
end;
end;
finally
SaveDialog.Free; // 释放保存对话框实例
end;
end;
这段代码的逻辑是允许用户将两个列表框(ListBox1
和 ListBox2
)中选中的项以及一个文本编辑框(Edit1
)中的内容导出到一个文本文件(.txt)中。以下是该逻辑的详细步骤:
-
创建保存对话框:首先,代码通过创建一个
TSaveDialog
实例来允许用户选择一个文件保存位置。这个对话框的标题被设置为“保存选中的项到TXT文件”,并且文件过滤器被设置为只显示文本文件(.txt)和所有文件(.)。 -
执行保存对话框:接着,代码调用
SaveDialog.Execute
方法来显示保存对话框。如果用户点击了“保存”按钮,那么对话框的FileName
属性将被设置为用户选择的文件名。 -
创建TStringList实例:如果用户选择了文件名,代码将创建一个
TStringList
实例sl
,用于存储将要写入文件的项。 -
加载旧内容(可选):如果目标文件已经存在,代码会尝试使用
sl.LoadFromFile(FileName)
方法加载该文件的内容到TStringList
中。这意味着如果用户想要将新内容追加到现有文件,这个步骤是必要的。 -
遍历列表框并添加选中项:代码接着遍历
ListBox1
和ListBox2
中的每一项,检查该项是否被选中(通过ListBoxX.Selected[i]
)。如果项被选中,则将其添加到TStringList
实例sl
中。 -
添加备注:之后,代码将
Edit1
文本编辑框中的内容作为备注添加到TStringList
中。 -
添加分隔符:为了区分文件内容的不同部分,代码向
TStringList
中添加了一个分隔符字符串('-------------------------'
)。 -
保存文件:最后,使用
sl.SaveToFile(FileName)
方法将TStringList
中的所有内容写入到用户选择的文件中。同时,文件名也被更新到Edit7
文本编辑框中,并向用户显示一个消息框,告知用户选中的项已成功导出到文件中。 -
资源释放:在
try...finally
块中,代码确保在退出之前释放了TStringList
和TSaveDialog
实例所占用的资源。
总的来说,这段代码提供了一种灵活的方式来将用户从两个列表框中选中的项以及一个文本编辑框中的内容导出到一个文本文件中,同时允许用户选择文件的保存位置和文件名。
“备注”输入框
这里有点“小心机”。编辑框初始化时,文字是浅色的,点击编辑框,内容消失,并且文字变为深色了。
{备注}
procedure TForm1.Edit1Enter(Sender: TObject);
begin
// 当Edit1获得焦点时,清空其内容
Edit1.Text := '';
Edit1.Font.Color:=clWindowText;
end;
画图软件
今天新发现的在线作图,能导入图片,但是刷新时不保存。
完整代码
代码在这。