function TBaseItem.MatchItem(const value: string): boolean;
begin
Result := (Pos(value, self.FDispCode) > 0) or (Pos(value, self.FHintCode) > 0)
or (Pos(value, self.FDispName) > 0);
end;
{ TFilterEdit }
constructor TFilterEdit.Create(AOwner: TComponent);
begin
inherited;
procedure TFilterEdit.CloseUp;
begin
self.FDropWindow.Hide;
self.FDropDown := false;
end;
procedure TFilterEdit.MouseDown(Button: TMouseButton; Shift: TShiftState;
X, Y: Integer);
begin
Windows.SetFocus(Handle);
if self.FDropDown then
CloseUp;
inherited;
end;
procedure TFilterEdit.SetSelectedItem(value: TBaseItem);
begin
self.FSelectedItem := value;
if Assigned(value) then
self.Text := value.DispCode + value.DispName
else
self.Text := '';
end;
procedure TFilterEdit.SetWindowHeight(const value: integer);
begin
if self.FWindowHeight <> value then
begin
self.FWindowHeight := value;
self.FDropWindow.Height := value;
end;
end;
procedure TFilterEdit.SetWindowPosition(var point: TPoint);
var
_Left : integer;
_Top : integer;
begin
_Left := point.X;
_Top := point.Y;
if (self.FWindowWidth + _Left) > Screen.Width then
_Left := _Left - (self.FWindowWidth - self.Width);
if self.FWindowHeight + _Top > Screen.Height then
_Top := _Top - self.FWindowHeight - self.Height;
point.X := _Left;
point.Y := _Top;
end;
procedure TFilterEdit.SetWindowWidth(const value: integer);
begin
if self.FWindowWidth <> value then
begin
self.FWindowWidth := value;
self.FDropWindow.Width := value;
end;
end;
procedure TFilterEdit.WMKillFocus(var Msg: TWMKillFocus);
begin
if (Msg.FocusedWnd <> self.FDropWindow.Handle) and (self.FDropDown) then
begin
CloseUp;
end;
end;
procedure TFilterEdit.WMChar(var Msg: TWMChar);
begin
inherited;
self.FSelectedItem := nil;
self.RefreshFilterList(self.Text);
if self.FDropDown then
self.FDropWindow.RefreshList
else if (self.FFilterItemList.Count > 0) then
self.DropDown;
end;
function TFilterEdit.GetItemCount: integer;
begin
Result := 0;
if Assigned(self.FItemList) then
Result := self.FItemList.Count;
end;
procedure TFilterEdit.SetItemList(const value: TStrings);
begin
if Assigned(self.FItemList) then
self.FItemList.Assign(value)
else
self.FItemList := value;
end;
procedure TFilterEdit.RefreshFilterList(filter: string);
var
i: integer;
item: TBaseItem;
begin
self.FFilterItemList.Clear;
for i := 0 to self.FItemList.Count-1 do
begin
item := TBaseItem(self.FItemList.Objects[i]);
if item.MatchItem(filter) then
self.FFilterItemList.AddObject(item.InCode, item);
end;
end;
{ TDropWindow }
constructor TDropWindow.Create(AOwner: TComponent);
begin
inherited CreateNew(AOwner);
self.BorderStyle := bsNone;
self.FListBox := TListBox.Create(self);
with self.FListBox do
begin
Parent := Self;
Align := alClient;
BorderStyle := bsNone;
Ctl3D := true;
OnKeyPress := ListBoxKeyPress;
// OnClick := SelectData;
end;
procedure TDropWindow.CreateParams(var Params: TCreateParams);
begin
inherited CreateParams(Params);
with Params do
begin
Style := WS_POPUP or WS_BORDER;
ExStyle := WS_EX_TOOLWINDOW;
AddBiDiModeExStyle(ExStyle);
WindowClass.Style := CS_SAVEBITS;
end;
end;
destructor TDropWindow.Destroy;
begin
self.FListBox.Free;
inherited;
end;
procedure TDropWindow.DoShow;
begin
self.RefreshList;
inherited;
end;
function TDropWindow.GetEdit: TFilterEdit;
begin
Result := TFilterEdit(self.Owner);
end;
function TDropWindow.GetForm: TWinControl;
begin
if (Owner <> nil) and (Owner.Owner <> nil) and (Owner.Owner is TWinControl) then
Result := Owner.Owner as TWinControl
else
Result := nil;
end;
procedure TDropWindow.ListBoxKeyPress(Sender: TObject; var Key: Char);
begin
if (key =#13) and (self.FListBox.Count > 0) and (self.FListBox.ItemIndex > -1) then
begin
self.Edit.SelectedItem := TBaseItem(self.FListBox.Items.Objects[self.FListBox.ItemIndex]);
self.Edit.CloseUp;
end;
end;
procedure TDropWindow.RefreshList;
var
i: integer;
item: TBaseItem;
begin
self.FListBox.Items.BeginUpdate;
self.FListBox.Items.Clear;
for i := 0 to self.Edit.FFilterItemList.Count-1 do
begin
item := TBaseItem(self.Edit.FFilterItemList.Objects[i]);
self.FListBox.Items.AddObject(item.DispCode + item.DispName, item);
end;
self.FListBox.Items.EndUpdate;
if self.FListBox.Count > 0 then
self.FListBox.ItemIndex := 0;
end;
procedure TDropWindow.SelectData(Sender: TObject);
begin
if (self.FListBox.Count > 0) and (self.FListBox.ItemIndex > -1) then
begin
self.Edit.SelectedItem := TBaseItem(self.FListBox.Items.Objects[self.FListBox.ItemIndex]);
self.Edit.CloseUp;
end;
end;
procedure TDropWindow.WMActivate(var Msg: TWMActivate);
var
OwnerForm : TWinControl;
MDIOwner : TCustomForm;
begin
inherited;
OwnerForm := GetForm;
if (Msg.Active = WA_ACTIVE) and (OwnerForm <> nil) then
begin
SendMessage(OwnerForm.Handle, WM_NCACTIVATE, 1, 0);
if (OwnerForm is TCustomForm) and (TForm(OwnerForm).FormStyle = fsMDIChild) then
begin
MDIOwner := Application.MainForm;
if MDIOwner <> nil then
SendMessage(MDIOwner.Handle, WM_NCACTIVATE, 1, 0);
end;
end;
if Msg.Active = WA_INACTIVE then
begin
self.Edit.CloseUp;
Hide;
end;
end;
procedure TDropWindow.WMMouseActivate(var Msg: TMessage);
begin
Msg.Result := MA_NOACTIVATE;
end;