如何从 TStringList 添加到 VirtualTreeView?

发布于 2024-10-28 19:41:34 字数 2134 浏览 1 评论 0原文

这就是我“试图”实现的目标,

我有一个生成密码的函数,然后将其添加到 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 天,如果有人能直接告诉我应该如何进行,那就太好了关于它。

克里斯

Here is what I am "trying" to achieve

I have a function to generate passwords which I then add into a TStringList after this I should populate the VirtualTreeView with the items but I am having no luck in getting anywhere fast with doing so. How should it be done the correct way? I am still learning and am not a professional.

My function for generating the passwords:

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;

Here is how I am calling it

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;

I expect that I am doing this completely the wrong way, I have been trying for 2 days now, it would be great if someone could put me straight with how I should go about it.

Chris

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

满身野味 2024-11-04 19:41:34

我可能会坚持使用 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;

您可以立即将数百万个项目放入其中。

I'd probably stick with TListView but turn it into a virtual list view. Like this:

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;

You can put millions of items in there in an instant.

粉红×色少女 2024-11-04 19:41:34

您最好将字符串列表存储在代码中的其他位置以“虚拟”使用它,例如在表单的私有部分中。填充后,只需设置:

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;

You better store your stringlist somewhere else in your code to use it "virtually", e.g. in the form's private section. When after populating it, just set:

vst1.Clear;
vst1.RootNodeCount := StrLst.Count;

And on tree's get text event:

procedure TForm1.vst1GetText(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex;
  TextType: TVSTTextType; var CellText: string);
begin
  CellText := StrLst[Node.Index];
end;
猫腻 2024-11-04 19:41:34

或者如果你真的想要 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 ->细绳

Or if you really want VirtualTreeView, you can use something like this ...
I'm not sure if this is absolutely clear solution, I'm familiar with records, not only one single variables.

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;

And you need to implement OnGetNodeDataSize and OnGetText events to initialize node data size and to display the text.

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;

Edit 1: I've corrected data types UnicodeString -> String

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文