TFindFrames

 

unit FindDM;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, DB, ExtCtrls, jpeg;

type
  TFindFrames = class(TFrame)
    edtValue: TEdit;
    cbFields: TComboBox;
    Label1: TLabel;
    Label2: TLabel;
    Timer: TTimer;
    procedure edtValueChange(Sender: TObject);
    procedure cbFieldsChange(Sender: TObject);
    procedure TimerTimer(Sender: TObject);
  private
    FDataSet: TDataSet;
    FSaveFilterRecord: TFilterRecordEvent;
    FSaveFiltered: Boolean;
    FDisplayFields: string;
    procedure ClearFields;
    procedure SetDataSet(const Value: TDataSet);
    procedure DataSetFilterRecord(ADataSet: TDataSet; var Accept: Boolean);
    procedure SetDisplayFields(const Value: string);
    procedure DisplayFieldsChanged;
    function GetDelay: Integer;
    procedure SetDelay(const Value: Integer);
  public
    { Public declarations }
    destructor Destroy; override;
    procedure Find;
    property Delay: Integer read GetDelay write SetDelay;
    property DataSet: TDataSet read FDataSet write SetDataSet;
    property DisplayFields: string read FDisplayFields write SetDisplayFields;
  end;

implementation

{$R *.dfm}

function GetHZPYM(const S: AnsiString): ansistring;
const
  ChinaCode: array[0..25, 0..1] of Integer = ((1601, 1636), (1637, 1832), (1833, 2077),
    (2078, 2273), (2274, 2301), (2302, 2432), (2433, 2593), (2594, 2786), (9999, 0000),
    (2787, 3105), (3106, 3211), (3212, 3471), (3472, 3634), (3635, 3722), (3723, 3729),
    (3730, 3857), (3858, 4026), (4027, 4085), (4086, 4389), (4390, 4557), (9999, 0000),
    (9999, 0000), (4558, 4683), (4684, 4924), (4925, 5248), (5249, 5589));
var
  i, j, HzOrd: Integer;
begin
  Result:='';
  i := 1;
  while i <= Length(s) do
  begin
    if (s[i] >= #160) and (s[i + 1] >= #160) then
    begin
      HzOrd := (Ord(s[i]) - 160) * 100 + Ord(s[i + 1]) - 160;
      for j := 0 to 25 do
      begin
        if (HzOrd >= ChinaCode[j][0]) and (HzOrd <= ChinaCode[j][1]) then
        begin
          Result := Result + Char(Byte('A') + j);
          Break;
        end;
      end;
      Inc(i);
    end else Result := Result + s[i];
    Inc(i);
  end;
end;

{ TFindFrames }

procedure TFindFrames.ClearFields;
var
  I: Integer;
  PS: PString;
begin
  for I := cbFields.Items.Count - 1 downto 0 do
  begin
    PS := Pointer(cbFields.Items.Objects[I]);
    Dispose(PS);
  end;
  cbFields.Clear;
end;

destructor TFindFrames.Destroy;
begin
  ClearFields;
  inherited;
end;

procedure TFindFrames.SetDataSet(const Value: TDataSet);
begin
  if FDataSet <> Value then
  begin
    if FDataSet <> nil then
    begin
      FDataSet.Filtered := False;
      FDataSet.OnFilterRecord := FSaveFilterRecord;
      FDataSet.Filtered := FSaveFiltered;
    end;
    FSaveFilterRecord := Value.OnFilterRecord;
    FSaveFiltered := Value.Filtered;
    FDataSet := Value;
    Value.OnFilterRecord := DataSetFilterRecord;
    DisplayFieldsChanged;
  end;
end;

procedure TFindFrames.Find;
begin
  with DataSet do
  begin
    DisableControls;
    try
      if edtValue.Text <> '' then Filtered := True
      else Filtered := False;
      First;
    finally
      EnableControls;
    end;
  end;
end;

procedure TFindFrames.DataSetFilterRecord(ADataSet: TDataSet;
  var Accept: Boolean);
var
  S: string;
begin
  S := ADataSet.FieldByName(PString(cbFields.Items.Objects[cbFields.ItemIndex])^).DisplayText;
  Accept := Pos(edtValue.Text, S) > 0;
  if not Accept then
    Accept := Pos(UpperCase(edtValue.Text), UpperCase(GetHZPYM(S))) > 0;
  if Accept and Assigned(FSaveFilterRecord) and FSaveFiltered then
    FSaveFilterRecord(ADataSet, Accept);
end;

procedure TFindFrames.edtValueChange(Sender: TObject);
begin
  if Delay = 0 then Find
  else begin
    Timer.Enabled := False;
    Timer.Enabled := True;
  end;
end;

procedure TFindFrames.cbFieldsChange(Sender: TObject);
begin
  Find;
end;

procedure TFindFrames.SetDisplayFields(const Value: string);
begin
  if FDisplayFields <> Value then
  begin
    FDisplayFields := Value;
    DisplayFieldsChanged;
  end;
end;

procedure TFindFrames.DisplayFieldsChanged;
var
  I: Integer;
  PS: PString;
  FieldList: TList;
begin
  ClearFields;
  if FDataSet <> nil then
  begin
    FieldList := TList.Create;
    try
      FDataSet.GetFieldList(FieldList, DisplayFields);
      for I := 0 to FDataSet.FieldCount - 1 do
        if ((FDisplayFields = '') and FDataSet.Fields[I].Visible) or
          (FieldList.IndexOf(FDataSet.Fields[I]) >= 0) then
        begin
          New(PS);
          PS^ := DataSet.Fields[I].FieldName;
          cbFields.Items.AddObject(DataSet.Fields[I].DisplayLabel, TObject(PS));
        end;
    finally
      FieldList.Free;
      Dispose(PS);
    end;
    if cbFields.Items.Count > 0 then cbFields.ItemIndex := 0;
  end;
end;

procedure TFindFrames.TimerTimer(Sender: TObject);
begin
  Timer.Enabled := False;
  Find;
end;

function TFindFrames.GetDelay: Integer;
begin
  Result := Timer.Interval;
end;

procedure TFindFrames.SetDelay(const Value: Integer);
begin
  Timer.Interval := Delay;
end;

end.

你可能感兴趣的:(frame)