8

VCL TDBGrid (Delphi XE2) で変更された「マスクされた」値を表示する必要があります。つまり、「password」を「xxxxxxxx」に変更するか、大文字の「pass」を「PASS」などに変更します。私のフィールドは動的に作成されるため(ただし、名前はコード化されているため、それらをマスクする方法とタイミングがわかります。つまり、パスワードフィールドの場合は xxxx_PASSW です)OnGetTextイベントを使用できません(私は思います)。

では、これを行う最も効率的な方法は何ですか (私はまだプレゼンテーションの変更に OnDrawColumnCell を使用しているので、使用したいと思います) ?

4

4 に答える 4

11

これを行うには少なくとも 3 つの方法があります。データベースからパスワード フィールドをマスクすることで説明します。SQL方言にSQLサーバーを使用しています。

1. SQL 文字列に計算フィールドを定義します。

select field1, field2, '********' as maskedPwd from table1;

次に、dbgrid を右クリックし、列エディターを選択します。dbgrid の列エディター内で、実際のパスワード列の代わりに maskedPwd 列を選択するだけです。これで、dbgrid はパスワードの代わりにマスクされた値を表示します。

また

2. dbgrid で使用されるデータセットで計算フィールドを定義します。

データセットを右クリックし、フィールド エディターを使用して新しい計算フィールドを作成します (例: maskedPwd2)。次に、データセットの onCalcField イベントで、maskedPwd2 の値を設定するコードを記述します。

procedure TForm1.ADOQuery1CalcFields(DataSet: TDataSet);
begin
  DataSet.FieldByName('maskedPwd2').AsString := '********';
end;

dbgrid の列エディターに maskedPwd2 が含まれていることを確認してください。

また

3. dbgrid の onDrawColumnCell イベントにカスタム テキストを書き込みます。

procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;
  DataCol: Integer; Column: TColumn; State: TGridDrawState);
var
  grid : TDBGrid;
  maskValue : String;
  aRect : TRect;
begin
  maskValue := '********';
  aRect := Rect;
  grid := sender as TDBGrid;

  if column.FieldName = 'password' then
  begin
    grid.Canvas.FillRect(Rect);
    DrawText(grid.Canvas.Handle, PChar(maskValue), Length(maskValue), aRect,
      DT_SINGLELINE or DT_LEFT or DT_VCENTER);
  end;
end;

上記のコードはマスクされた値のみを表示することに注意してください。ただし、グリッドが編集可能な場合、セルがフォーカスまたは編集されると実際のパスワード値が表示されます。

これに対処するには、TEdit をフォームにドロップし、text プロパティをクリアし、PpasswordChar プロパティを '*' に設定し、visible を false に設定します。これで、セルの組み込みエディターの代わりとして使用する準備が整いました。ここで、いくつかの接着ロジックが必要です。

procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;
  DataCol: Integer; Column: TColumn; State: TGridDrawState);
var
  grid : TDBGrid;
  maskValue : String;
  aRect : TRect;
begin
  maskValue := '********';
  aRect := Rect;
  grid := sender as TDBGrid;

  if column.FieldName = 'password' then
    if gdfocused in State then
      begin
        Edit1.Left := Rect.Left + grid.Left + 1;
        Edit1.Top  := rect.Top + grid.Top + 1;
        Edit1.Width := Rect.Right - Rect.Left + 2;
        Edit1.Height := Rect.Bottom - Rect.Top + 2;
        Edit1.Clear;
        Edit1.Visible := True;
      end
    else
      begin
        grid.Canvas.FillRect(Rect);
        DrawText(grid.Canvas.Handle, PChar(maskValue), Length(maskValue), aRect,
          DT_SINGLELINE or DT_LEFT or DT_VCENTER);
      end
  else
    grid.DefaultDrawColumnCell(Rect, DataCol, Column, state);
end;

procedure TForm1.DBGrid1ColExit(Sender: TObject);
begin
  Edit1.Visible := False;
end;

procedure TForm1.DBGrid1KeyPress(Sender: TObject; var Key: Char);
begin
  if Key = Chr(9) then Exit;

  if (Sender as TDBGrid).SelectedField.FieldName = 'password' then
  begin
    Edit1.SetFocus;
    SendMessage(Edit1.Handle, WM_CHAR, word(Key), 0);
  end;
end;

procedure TForm1.Edit1Change(Sender: TObject);
begin
  if DBGrid1.DataSource.State in [dsEdit, dsInsert] then
    DBGrid1.DataSource.DataSet.FieldByName('password').AsString := Edit1.Text;
end;

procedure TForm1.Edit1Enter(Sender: TObject);
begin
  DBGrid1.DataSource.Edit;
end;

上記のコードはまだ完全ではありませんが、本質はそこにあります。運動はお任せします。

于 2012-09-21T04:32:47.650 に答える
5

OnGetTextフィールドの値はどのコントロールにも表示されるべきではないため、データセットのパスワード フィールドにを記述します。

于 2012-09-19T15:56:23.300 に答える
2

列全体のすべての値をマスクする必要がありますか? その場合、これを行う TField (またはフィールド名) がわかっている場合: 変更された値を使用して計算フィールドを動的に作成し、それを列に表示してみてください。

于 2012-09-20T06:39:15.743 に答える
1

上記のコードを変更して、パスワードを表示および非表示にします。ユーザーがパスワードセルをクリックすると表示され、セルをクリックすると再び非表示になります。

// Add a cell click event from the TDBGrid
procedure TForm1.DBGrid1CellClick(Column: TColumn);
begin
if DBGrid1.SelectedField.FieldName = 'password' then
Edit1.Text := Your_Table_Name.FieldByName('password').AsString;
Edit1.PasswordChar:=#0;
end;

// Change the edit1change event to this
procedure TForm1.Edit1Change(Sender: TObject);
begin
if DBGrid1.DataSource.State in [dsEdit, dsInsert] then
Your_Table_Name.FieldByName('password').AsString := Edit1.Text;
Edit1.PasswordChar:=#0;
end;

// You should change colexit event to read like this
procedure TForm1.DBGrid1ColExit(Sender: TObject);
begin
if DBGrid1.SelectedField.FieldName = 'password' then
Edit1.Visible := False;
end; 

クールなパスワードフィールドにするのにそれほど手間はかかりませんでした。

DBGrid の Draw Column Cell イベントで忘れていたことが 1 つあります。Edit1.Clear を変更する必要があります。Edit1.Text へ:= Your_Table_Name.FieldByName('Password').AsString;

于 2014-08-18T14:25:59.867 に答える