这就是我“努力”实现的目标
我有一个生成密码的函数,然后我将其添加到TStringList中,之后我应该使用这些项填充VirtualTreeView,但是我没有运气这么做。应该如何以正确的方式完成?我还在学习,不是专业人士。
我生成密码的功能:
function Generate(AllowUpper,AllowLower,AllowNumbers,AllowSymbols:Boolean; PassLen:Integer):String;
const
UpperList = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
LowerList = 'abcdefghijklmnopqrstuvwxyz';
NumberList = '0123456789';
SymbolList = '!#$%&/()=?@<>|{[]}\*~+#;:.-_';
var
MyList : String;
Index : Integer;
i : Integer;
begin
Result:='';
MyList:='';
//here if the flag is set the elements are added to the main array (string) to process
if AllowUpper then MyList := MyList + UpperList;
if AllowLower then MyList := MyList + LowerList;
if AllowNumbers then MyList := MyList + NumberList;
if AllowSymbols then MyList := MyList + SymbolList;
Randomize;
if Length(MyList)>0 then
for i := 1 to PassLen do
begin
Index := Random(Length(MyList))+1;
Result := Result+MyList[Index];
end;
end;
以下是我如何称呼它
procedure TMain.Button3Click(Sender: TObject);
var
i: integer;
StrLst: TStringList;
// Timing vars...
Freq, StartCount, StopCount: Int64;
TimingSeconds: real;
begin
vst1.Clear;
Panel2.Caption := 'Generating Passwords...';
Application.ProcessMessages;
// Start Performance Timer...
QueryPerformanceFrequency(Freq);
QueryPerformanceCounter(StartCount);
StrLst := TStringList.Create;
try
for i := 1 to PassLenEd.Value do
StrLst.Add(Generate(ChkGrpCharSelect.Checked[0],ChkGrpCharSelect.Checked[1],
ChkGrpCharSelect.Checked[2],ChkGrpCharSelect.Checked[3],20));
// Stop Performance Timer...
QueryPerformanceCounter(StopCount);
TimingSeconds := (StopCount - StartCount) / Freq;
// Display Timing... How long it took to generate
Panel2.Caption := 'Generated '+IntToStr(PassLenEd.Value)+' passwords in '+
FloatToStrF(TimingSeconds,ffnumber,1,3)+' seconds';
// Add to VirtualTreeList - here???
finally
StrLst.Free;
end;
end;
我希望我这样做完全是错误的,我现在已经尝试了2天,如果有人可以直截了当地告诉我应该怎么做,那就太好了。
克里斯
答案 0 :(得分:7)
我可能会坚持使用TListView,但将其转换为虚拟列表视图。像这样:
procedure TMyForm.FormCreate;
begin
ListView.OwnerData := True;
ListView.OnData = ListViewData;
ListView.Items.Count := StringList.Count;
end;
procedure TMyForm.ListViewData(Sender: TObject; ListItem: TListItem);
begin
ListItem.Caption := StringList[ListItem.Index];
end;
您可以立即将数百万件物品放入其中。
答案 1 :(得分:3)
您最好将字符串列表存储在代码中的其他位置,以“虚拟”使用它,例如在表格的私人部分。填充后,只需设置:
vst1.Clear;
vst1.RootNodeCount := StrLst.Count;
在树的获取文本事件:
procedure TForm1.vst1GetText(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex;
TextType: TVSTTextType; var CellText: string);
begin
CellText := StrLst[Node.Index];
end;
答案 2 :(得分:2)
或者,如果你真的想要VirtualTreeView,你可以使用这样的东西...... 我不确定这是否是绝对清晰的解决方案,我熟悉记录,而不仅仅是一个变量。
procedure TMain.Button3Click(Sender: TObject);
var i: integer;
p: PString;
Freq, StartCount, StopCount: Int64;
TimingSeconds: real;
begin
Panel2.Caption := 'Generating Passwords...';
Application.ProcessMessages;
QueryPerformanceFrequency(Freq);
QueryPerformanceCounter(StartCount);
vst1.BeginUpdate;
vst1.Clear;
for i := 1 to PassLenEd.Value do
begin
p := VirtualStringTree1.GetNodeData(VirtualStringTree1.AddChild(nil));
p^ := Generate(ChkGrpCharSelect.Checked[0],ChkGrpCharSelect.Checked[1], ChkGrpCharSelect.Checked[2],ChkGrpCharSelect.Checked[3],20);
end;
vst1.EndUpdate;
QueryPerformanceCounter(StopCount);
TimingSeconds := (StopCount - StartCount) / Freq;
Panel2.Caption := 'Generated '+IntToStr(PassLenEd.Value)+' passwords in '+
FloatToStrF(TimingSeconds,ffnumber,1,3)+' seconds';
end;
您需要实现OnGetNodeDataSize和OnGetText事件来初始化节点数据大小并显示文本。
procedure TMain.vst1GetNodeDataSize(
Sender: TBaseVirtualTree; var NodeDataSize: Integer);
begin
NodeDataSize := SizeOf(string);
end;
procedure TMain.vst1GetText(Sender: TBaseVirtualTree;
Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType;
var CellText: string);
begin
CellText := PString(VirtualStringTree1.GetNodeData(Node))^;
end;
编辑1:我已更正数据类型UnicodeString - &gt;串