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.