📄 ottedit.pas
字号:
{
*******************************************************************************
* 本控件由stuwe个人开发,其中部分加密代码来源于网络,如侵犯了您的权益,请联系我 *
* 本控件包包括ottEnter, ottDBGrid, ottEdit, ottDBEdit控件 *
* 该控件请勿用于商业用途,如需商业使用请与本人联系 *
* 本人联系方式: QQ : 31926588 *
* MSN : ottsoft@hotmail.com *
* EMail : stuwe@163.com *
* 以下为ottEdit控件代码 *
*******************************************************************************
}
unit ottEdit;
interface
uses
SysUtils, Classes, Controls, StdCtrls, ADODB, DB, ottDBEdit, ottThread, Menus,
Forms, Windows, DBGrids;
type
TottEdit = class(TEdit)
private
{ Private declarations }
FVersion: string;
DataPack: _RecordSet;
FConnection: TADOConnection; //查询数据所使用的连接 ADOConnection
FFindQuery: TADOQuery; //查询数据所用的 ADOQuery
FFindSource: TDataSource; //查询数据所用的数据集关联的 数据源
FListGrid: TottDBGrid;
FSQL: TStrings;
FPopupMenu: TottPopupMenu; //保存右键菜单
FDefaultKeyValue: string;//保存上一次的正确值;
FDefaultResultValue: String;//保存上一次正确的Lookup值
FKeyValue: String; //关联字段名
FListValue: String; // LookupResult 字段名
FLookupKeyField: String;
FLookupResultField: String;
FListColumnWidth: String; //显示Grid的各列宽度
FListGridWidth: Integer; //显示Grid的宽度
FListGridHeight: Integer; //显示Grid的高度
FIsLike: Boolean;//是否进行全部模糊查询
FAutoList: Boolean; //是否自动列出数据标识true为自动列出,false为输入时列出
FInputFlag: Boolean; //标志输入状态 true为输入状态, false为正常状态
FInputParam: Integer; //当前输入参数为第几参数
FMaxRecord: Integer; //显示的记录数
FLocalFilter: Boolean; //是否进行本地过滤查询,如果进行本地查询的话需要调用初始化数据过程对数据进行初始化
FLocalFilterFields: TStrings; //本地过滤查询的对应字段
FLocalFilterSQL: WideString; //本地过滤查询初始化数据使用的语句
FAutoInit: Boolean;//设置是否自动初始化(配合本地过滤设置使用),如果设置了自动初始化,控件创建过程自动初始化
FInitThread: TInitThread;//初始化数据线程
FParams: TParams; //设置其它查询参数,从第5个起
FOnEnter: TNotifyEvent;//保存控件的OnEnter事件
FOnExit: TNotifyEvent;//保存控件的OnExist事件
FOnChange: TNotifyEvent; //保存控件的OnChange事件
FOnKeyDown: TKeyEvent; //保存控件的KeyDown事件
FOnSelectValue: TNotifyEvent; //选择上值后所做的操作
procedure SetConnection(Value: TADOConnection);//设置连接的ADOConnection
procedure SetListGrid(Value: TottDBGrid); //设置显示的数据的Grid;
function GetSQL: TStrings;
procedure SetSQL(const Value: TStrings);
function GetFilterField: TStrings;
procedure SetFilterField(const Value: TStrings);
procedure SetInputParam(Value: Integer);
procedure SetLocatFilter(Value: Boolean);
procedure SetListColumnWidth(Value: String);
procedure SetListGridWidth(Value: Integer);
procedure SetListGridHeight(Value: Integer);
procedure SetParams(Value: TParams);
procedure SetLocalFilterSQL(Value: WideString);
procedure SetAutoInit(Value: Boolean);
procedure OnThreadDown(Sender: TObject);
protected
{ Protected declarations }
procedure ottChange(Sender: TObject); //改变数据事件
procedure ottEnter(Sender: TObject); //获得焦点事件
procedure ottExit(Sender: TObject); //失去焦点事件
procedure ottKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
procedure SearchData; //根据数据状态查找数据
procedure HideListGrid; //隐藏掉选值列表
procedure CheckInvaildValue;//检查输入内容是否正确,不正确清除掉数据或返回
//procedure BuilderField;
procedure SetListGridColumn; //根据FListColumnWidth设置的值设置ListGrid的列宽
procedure Notification(AComponent: TComponent;
Operation: TOperation); override;
procedure Loaded; override;
public
{ Public declarations }
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure Init(); //如果设置启用LocatFilter(本地过滤),则必须调用init初始化数据过程
published
{ Published declarations }
property SQL: TStrings read GetSQL write SetSQL;
property IsLike: Boolean read FIsLike write FIsLike default False;
property KeyValue: String read FKeyValue;
property ResultValue: string read FListValue;
property LookupKeyField: string read FLookupKeyField write FLookupKeyField;
property LookupResultField: string read FLookupResultField write FLookupResultField;
property Connection: TADOConnection read FConnection write SetConnection;
property AutoList: Boolean read FAutoList write FAutoList;
property OnSelectValue: TNotifyEvent read FOnSelectValue write FOnSelectValue;
property ListGrid: TottDBGrid read FListGrid write SetListGrid;
property InputParam: Integer read FInputParam write SetInputParam;
property ListColumnWidth: String Read FListColumnWidth write SetListColumnWidth;
property ListGridWidth: Integer read FListGridWidth write SetListGridWidth default 0;
property ListGridHeight: Integer read FListGridHeight write SetListGridHeight default 0;
property Params: TParams read FParams write SetParams;
property LocalFilterFields: TStrings read GetFilterField write SetFilterField;
property LocalFilterSQL: WideString read FLocalFilterSQL write SetLocalFilterSQL;
property LocalFilter: Boolean read FLocalFilter write SetLocatFilter;
property AutoInit: Boolean read FAutoInit write SetAutoInit default false;
property MaxRecord: Integer read FMaxRecord write FMaxRecord;
property Version: string read FVersion;
end;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents('ottLib', [TottEdit]);
end;
{ TottEdit }
procedure TottEdit.CheckInvaildValue;
begin
if not (csLoading in ComponentState) then
begin
if FFindQuery.Active then
if not FFindQuery.Locate(FLookupKeyField, FKeyValue, [loCaseInsensitive, loPartialKey]) then
begin
FKeyValue := FDefaultKeyValue;
FListValue := FDefaultResultValue;
end
else
begin
FDefaultKeyValue := FKeyValue;
FDefaultResultValue := FListValue;
end;
end;
end;
constructor TottEdit.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FVersion := 'OttLib 1.0';
FMaxRecord := 10; //初始化查询条目为10
FInputParam := 0; //初始化查询参数为第一个
// FDefaultField := DataField;
FSQL := TStringList.Create;
FLocalFilterFields := TStringList.Create;
FParams := TParams.Create(self);
if Assigned(OnChange) then
FOnChange := OnChange;
OnChange := ottChange;
if Assigned(OnEnter) then
FOnEnter := OnEnter;
OnEnter := ottEnter;
if Assigned(OnExit) then
FOnExit := OnExit;
OnExit := ottExit;
if Assigned(OnKeyDown) then
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 TottEdit.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 TottEdit.GetFilterField: TStrings;
begin
Result := FLocalFilterFields;
end;
function TottEdit.GetSQL: TStrings;
begin
Result := FSQL;
end;
procedure TottEdit.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 TottEdit.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 TottEdit.Loaded;
begin
inherited;
if FAutoInit then
Init;
end;
procedure TottEdit.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;
end;
end;
procedure TottEdit.OnThreadDown(Sender: TObject);
begin
if FLocalFilter then
begin
if Assigned(DataPack) then
FFindQuery.Recordset := DataPack;
end;
end;
procedure TottEdit.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 TottEdit.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
//BuilderField;//先生成字段信息
Text := FKeyValue;
SelectAll;
if Assigned(FListGrid) then
begin
FListGrid.SetActiveControl(TWinControl(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;
if Assigned(FOnEnter) then
FOnEnter(Sender);
end;
procedure TottEdit.ottExit(Sender: TObject);
begin
if Sender is ClassType then
begin
if Assigned(FListGrid) then
begin
if not FListGrid.Focused then
begin
CheckInvaildValue;
Text := FListValue;
HideListGrid;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -