📄 ottdbedit.pas
字号:
FOnKeyDown := OnKeyDown;
OnKeyDown := ottKeyDown;
FInitThread := nil;
DataPack := nil;
if not (csDesigning in ComponentState) then
begin
//设置右键弹出菜单
FPopupMenu := TottPopupMenu.Create(self);
PopupMenu := FPopupMenu;
PopupMenu.AutoHotkeys := maManual;
if Assigned(PopupMenu.OnPopup) then
PopupMenu.OnPopup(PopupMenu);
//初始化查询数据集及数据源
FFindQuery := TADOQuery.Create(self);
FFindQuery.ParamCheck := true;
if Assigned(FConnection) then
FFindQuery.Connection := FConnection;
FFindQuery.SQL.Assign(FSQL);
FFindSource := TDataSource.Create(self);
FFindSource.DataSet := FFindQuery;
end;
BuilderField; //生成字段信息
if FAutoInit and FLocalFilter then //如果设置为自动初始化及本地查询,则调用初始化函数初始化数据
Init();
end;
destructor TottDBEdit.Destroy;
begin
if Assigned(FInitThread) then
FInitThread.Terminate;
if not (csDesigning in ComponentState) then
begin
FreeAndNil(FFindQuery);
FreeAndNil(FFindSource);
end;
inherited;
FreeAndNil(FSQL);
FreeAndNil(FLocalFilterFields);
FParams.Free;
end;
function TottDBEdit.GetFilterField: TStrings;
begin
Result := FLocalFilterFields;
end;
function TottDBEdit.GetSQL: TStrings;
begin
Result := FSQL;
end;
procedure TottDBEdit.HideListGrid;
begin
if Assigned(FListGrid) then
begin
if FListGrid.Visible then
begin
FInputFlag := false;
if not Focused then //控件得不到焦点,则清除掉关联的DataSource
FListGrid.DataSource := nil;
FListGrid.Hide;
FListGrid.SendToBack;
end;
end;
end;
procedure TottDBEdit.Init();
begin
if not (csDesigning in ComponentState) then
if FLocalFilter then //必须是设置为本地查找才会执行初始化数据过程
begin
if Assigned(FInitThread) then //判断初始化线程是否存在,存在则停止掉线程再进行初始化
FInitThread.Terminate;
if Assigned(FConnection) then
begin
FInitThread := TInitThread.Create(FConnection, FLocalFilterSQL, DataPack);
FInitThread.OnTerminate := OnThreadDown;
end;
end;
end;
procedure TottDBEdit.Loaded;
begin
inherited Loaded;
if FAutoInit then
Init;
end;
procedure TottDBEdit.Notification(AComponent: TComponent;
Operation: TOperation);
begin
inherited Notification(AComponent, Operation);
if (Operation = opRemove) then
begin
if (AComponent = FConnection) then
FConnection := nil;
if (AComponent = FListGrid) then
FListGrid := nil;
if (AComponent = FLookupDataSet) then
FLookupDataSet := nil;
end;
end;
procedure TottDBEdit.OnThreadDown(Sender: TObject);
begin
if FLocalFilter then
begin
if Assigned(DataPack) then
FFindQuery.Recordset := DataPack;
end;
end;
procedure TottDBEdit.ottChange(Sender: TObject);
begin
if Sender is ClassType then
begin
if FInputFlag then //当前状态为可修改状态
begin
SearchData;
if Assigned(FListGrid) then
begin
FListGrid.Visible := true;
FListGrid.Show;
FListGrid.BringToFront;
end;
end
else
HideListGrid;
end;
if Assigned(FOnChange) then
FOnChange(Sender);
end;
procedure TottDBEdit.ottEnter(Sender: TObject);
procedure SetGridToRoot(Grid: TottDBGrid; gParent: TWinControl);
begin
if gParent is TCustomForm then
Grid.Parent := gParent
else
SetGridToRoot(Grid, gParent.Parent);
end;
procedure SetGridPos;
var p: TPoint;
begin
p.X := Left;
p.Y := Top;
FListGrid.Left := FListGrid.Parent.ScreenToClient(Parent.ClientToScreen(p)).x;
FListGrid.Top := FListGrid.Parent.ScreenToClient(Parent.ClientToScreen(p)).y + Height;
if (FListGrid.Left + FListGrid.Width) > FListGrid.Parent.ClientWidth then
FListGrid.Left := FListGrid.Parent.ClientWidth - FListGrid.Width;
if FListGrid.Left < 0 then
begin
FListGrid.Width := FListGrid.Parent.ClientWidth;
FListGrid.Left := 0;
end;
if (FListGrid.Top + FListGrid.Height) > FListGrid.Parent.ClientHeight then
FListGrid.Top := FListGrid.Top - FListGrid.Height - Height;
end;
begin
if Sender is ClassType then
begin
if Assigned(DataSource) then
if Assigned(DataSource.DataSet) then
if DataSource.DataSet.Active then
begin
BuilderField;//先生成字段信息
if FKeyField <> '' then
DataField := FKeyField
else
DataField := FDefaultField;
SelectAll;
if Assigned(FListGrid) then
begin
FListGrid.SetActiveControl(self);
if Assigned(FFindSource) then
FListGrid.DataSource := FFindSource;
SetGridToRoot(FListGrid, FListGrid.Parent); //设置显示数据Grid的Parent为所在的窗体
SetGridPos; //设置显示数据Grid的位置跟控件一致
if FAutoList then
begin
if not FInputFlag then
SearchData;
FListGrid.Show;
FListGrid.BringToFront;
end;
//SetListGridColumn;
end;
end;
end;
if Assigned(FOnEnter) then
FOnEnter(Sender);
end;
procedure TottDBEdit.ottExit(Sender: TObject);
begin
if Sender is ClassType then
begin
if Assigned(FListGrid) then
begin
//raise exception.Create('eeee');
if not FListGrid.Focused then
begin
CheckInvaildValue;
if FListField <> '' then
DataField := FListField
else
DataField := FDefaultField;
HideListGrid;
end
else
begin
if FKeyField <> '' then
DataField := FKeyField
else
DataField := FDefaultField;
end;
end;
end;//if Sender is ClassType then
if Assigned(FOnExit) then
FOnExit(Sender);
end;
procedure TottDBEdit.ottKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
if Sender is ClassType then
begin
if Assigned(DataSource) then
if Assigned(DataSource.DataSet) then
if DataSource.DataSet.CanModify then
if Key in [VK_UP, VK_DOWN, VK_RETURN, VK_ESCAPE] then
begin
if Assigned(FListGrid) then
begin
if FListGrid.Visible then
begin
if Assigned(FListGrid.DataSource) then
begin
if Assigned(FListGrid.DataSource.DataSet) then
begin
if FListGrid.DataSource.DataSet.Active then
begin
if Key = VK_UP then
begin
FListGrid.DataSource.DataSet.Prior;
Key := 0;
end
else if Key = VK_DOWN then
begin
FListGrid.DataSource.DataSet.Next;
Key := 0;
end
else if Key = VK_ESCAPE then
begin
CheckInvaildValue;
HideListGrid;
if not (Focused or FListGrid.Focused) then
ottExit(self);
end
else if Key = VK_RETURN then
begin
if not FFindQuery.IsEmpty then
begin
if not(DataSource.DataSet.State in [dsEdit, dsInsert]) then
DataSource.DataSet.Edit;
if FFindQuery.FindField(FLookupKeyField) <> nil then
DataSource.DataSet.FieldByName(FKeyField).Value := FFindQuery.FieldByName(FLookupKeyField).Value
else
DataSource.DataSet.FieldByName(FKeyField).Value := FFindQuery.Fields[0].Value;
if Assigned(FOnSelectValue) then
FOnSelectValue(self);
HideListGrid;
SetFocus;
PostMessage(Handle, $0100, VK_TAB, 0);
end;
Key := 0;
end;
end; //if FListGrid.DataSource.DataSet.Active then
end;//if Assigned(FListGrid.DataSource.DataSet) then
end;//if Assigned(FListGrid.DataSource) then
end; //if FListGrid.Visible then
end;//if Assigned(FListGrid) then
end //if Key in [VK_UP, VK_DOWN, VK_RETURN, VK_ESCAPE] then
else
begin
FInputFlag := true;
end;
end;//if Sender is ClassType then
if Key = VK_RETURN then
PostMessage(Handle, $0100, VK_TAB, 0);
if Assigned(FOnKeyDown) then
FOnKeyDown(Sender, Key, Shift);
end;
procedure TottDBEdit.SearchData;
var i: integer;
fStr: String;
begin
if Assigned(FFindQuery) then
begin
if Assigned(FConnection) then
begin
with FFindQuery do
begin
DisableControls;
try
if FLocalFilter then //以下代码为处理本地过滤查找的
begin
FFindQuery.Filtered := false;
fStr := '';
if FInputFlag then
begin
for i := 0 to FLocalFilterFields.Count-1 do
begin
if i = FInputParam then
if Trim(Text)<>'' then
begin
if FIsLike then
fStr := fStr + FLocalFilterFields.Strings[i] + ' like '+QuotedStr('*'+UpperCase(Trim(Text))+'*')+' and '
else
fStr := fStr + FLocalFilterFields.Strings[i] + ' like '+QuotedStr(UpperCase(Trim(Text))+'*')+' and ';
end;
if (i>3)and((i-3)<=FParams.Count) then
fStr := fStr + FLocalFilterFields.Strings[i] + '='+ QuotedStr(FParams.Items[i-4].AsString)+' and ';
end;
if Length(fStr)>4 then
System.Delete(fStr, Length(fStr)-4, 4);
end
else
begin
for i := 0 to FLocalFilterFields.Count-1 do
begin
if i = 2 then
if Trim(Text)<>'' then
if FIsLike then
fStr := fStr + FLocalFilterFields.Strings[i] + ' like '+QuotedStr('*'+UpperCase(Trim(Text))+'*')+' and '
else
fStr := fStr + FLocalFilterFields.Strings[i] + ' like '+QuotedStr(UpperCase(Trim(Text))+'*')+' and ';
if (i>3)and((i-3)<=FParams.Count) then
fStr := fStr + FLocalFilterFields.Strings[i] + '='+ QuotedStr(FParams.Items[i-4].AsString)+' and ';
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -