⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ottedit.pas

📁 OttLib套件使用说明: 1、OttEnter控件:该控件主要实现在窗口中按回车键跳转到下一控件的功能;该控件是非可视控件
💻 PAS
📖 第 1 页 / 共 2 页
字号:
{
*******************************************************************************
*  本控件由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 + -