1

これが私が達成しようとしていることです

パスワードを生成する関数があり、これを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日間試してみましたが、誰かが私にそれをどうやってやるべきかをまっすぐに教えてくれたら素晴らしいと思います。

クリス

4

3 に答える 3

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;

そこに何百万ものアイテムを瞬時に入れることができます。

于 2011-03-31T15:13:16.577 に答える
3

文字列リストをコード内の別の場所に保存して、「仮想的に」使用することをお勧めします。たとえば、フォームのプライベートセクションなどです。入力した後、次のように設定します。

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

そして、ツリーのget textイベントで:

procedure TForm1.vst1GetText(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex;
  TextType: TVSTTextType; var CellText: string);
begin
  CellText := StrLst[Node.Index];
end;
于 2011-03-31T16:27:43.117 に答える
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-> String

于 2011-03-31T16:28:58.063 に答える