程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> Delphi >> 偶寫的第一個控件,一個用選擇代替輸入的Edit控件

偶寫的第一個控件,一個用選擇代替輸入的Edit控件

編輯:Delphi
{***************************************************************}
  {                                                               }
  {             Siow寫的第一個控件                                }
  {                                                               }
  {用途:主要用於數據錄入界面                                     }
  {特點:用選擇代替輸入,減少人工錄入時的低級錯誤                 }
  {版本:V1.1                                                     }
  {已知Bugs:1、在設計期如果數據源Active就無法編譯                 }
  {         2、ConnectionString編緝問題。加上ADOReg,DesignIntf後,}
  {            控件可安裝卻有好多引用單元無法編譯,郁悶-_-!        }
  {聯系方式:E-Mail:[email protected]                             }
  {          QQ:1253366                                           }
  {                                                               }
  {                                                               }
  {***************************************************************}

  
  unit DBLookUpEdit;

  interface

  uses
    Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
    Dialogs, Grids, DBGrids, StdCtrls, DB, ADODB;
    //,ADOReg,DesignIntf,DesignEditors
  type

    {TDBLookUpEdit}

    TDBLookUpEdit = class(TEdit)
    private
      FCreating:   Boolean;
      FKeyField:   WideString;
      FDBGrid :    TDBGrid;
      FADOQuery:   TADOQuery;
      FDataSource: TDataSource;
      FOnEnter:    TNotifyEvent;
      FOnExit:     TNotifyEvent;
      FOnChange:   TNotifyEvent;
      //FOnClick: TNotiFyEvent;
      //FOnDblClick:TNotifyEvent;
      procedure CNCommand(var Message: TWMCommand);
        message CN_COMMAND;
      function GetActive: Boolean;
      procedure SetActive(Value: Boolean);
      function  GetDataSource: TDataSource;
      procedure SetDataSource(Value: TDataSource);
      function GetConnectionString: WideString;
      procedure SetConnectionString(const Value: WideString);
      function GetConnection: TADOConnection;
      procedure SetConnection(const Value: TADOConnection);
      function GetSQL: TStrings;
      procedure SetSQL(const Value: TStrings);
      procedure SetRecText(FieldNo: integer);
      procedure DoFDBGridMouseUp(Sender: TObject; Button: TMouseButton;Shift: TShiftState; X, Y: Integer);
      procedure DoFDBGridKeyDown(Sender: TObject; var Key: Word;Shift: TShiftState);
    protected
      procedure SetParent(AParent: TWinControl); override;
      procedure Notification(AComponent: TComponent; Operation: TOperation); override;
      procedure CMVisiblechanged(var Message: TMessage);
        message CM_VISIBLECHANGED;
      procedure CMEnabledchanged(var Message: TMessage);
        message CM_ENABLEDCHANGED;
      procedure CMBidimodechanged(var Message: TMessage);
        message CM_BIDIMODECHANGED;
      procedure FDoEnter(Sender: TObject);
      procedure FDoExit(Sender: TObject);
      procedure KeyDown(var Key: Word; Shift: TShiftState); override;
      procedure KeyPress(var Key: Char); override;
      procedure KeyUp(var Key: Word; Shift: TShiftState); override;
      procedure Loaded; override;
      procedure CreateWnd; override;
    public
      constructor Create(AOwner: TComponent); override;
      procedure SetBounds(ALeft: Integer; ATop: Integer; AWidth: Integer; AHeight: Integer); override;

    published
      //procedure Click;override;
      property KeyFieldName:WideString read FKeyField write FKeyField;
      procedure DblClick; override;
      property OnEnter: TNotifyEvent read FOnEnter write FOnEnter;
      property OnExit: TNotifyEvent read FOnExit write FOnExit;
      property OnChange: TNotifyEvent read FOnChange write FOnChange;
      //property OnClick: TNotifyEvent read FOnClick write FOnClick;
      //property OnDblClick: TNotifyEvent read FOnDblClick write FOnDblClick;
      //property DataSource: TDataSource read GetDataSource write SetDataSource;
      property Active: Boolean read GetActive write SetActive default False;
      property ConnectionString: WideString read GetConnectionString write SetConnectionString;
      property Connection: TADOConnection read GetConnection write SetConnection;
      property SQL: TStrings read GetSQL write SetSQL;
    end;

  procedure Register;

  implementation

  { TDBLookUpEdit }

  procedure Register;
  begin
    RegisterComponents('LD Controls', [TDBLookUpEdit]);
    //RegisterPropertyEditor(TypeInfo(WideString), TDBLookUpEdit, 'ConnectionString', TConnectionStringProperty);
  end;

  constructor TDBLookUpEdit.Create(AOwner: TComponent);
  begin
    inherited;
    FDBGrid     :=TDBGrid.Create(Self);
    FADOQuery   :=TADOQuery.Create(self);
    FDataSource :=TDataSource.Create(self);

    FDBGrid.FreeNotification(self);
    FADOQuery.FreeNotification(self);
    FDataSource.FreeNotification(self);

    FDataSource.DataSet:=FADOQuery;
    with FDBGrid do
    begin
      DataSource:=FDataSource;
      Ctl3D:=false;
      Visible:=false;
      ParentCtl3D:=false;
      Options:=[dgColLines,dgRowLines,dgRowSelect,dgAlwaysShowSelection,dgConfirmDelete,dgCancelOnExit];
      OnMouseUp:=DoFDBGridMouseUp;
      OnKeyDown:=DoFDBGridKeyDown;
    end;

    with self do
    begin
      ParentCtl3D:=false;
      Ctl3D:=false;
    end;
  end;

  procedure TDBLookUpEdit.CreateWnd;
  begin
    FCreating := True;
    try
      inherited CreateWnd;
    finally
      FCreating := False;
    end;
  end;

  procedure TDBLookUpEdit.CMBidimodechanged(var Message: TMessage);
  begin
    inherited;
    FDBGrid.BiDiMode := BiDiMode;
  end;

  procedure TDBLookUpEdit.CMEnabledchanged(var Message: TMessage);
  begin
    inherited;
    FDBGrid.Enabled := Enabled;
  end;

  procedure TDBLookUpEdit.CMVisiblechanged(var Message: TMessage);
  begin
    inherited;
  end;

  procedure TDBLookUpEdit.Notification(AComponent: TComponent;
    Operation: TOperation);
  begin
    inherited Notification(AComponent, Operation);
    if (AComponent = FDBGrid) and (Operation = opRemove) then  FDBGrid:= nil;
    if (AComponent = FADOQuery) and (Operation = opRemove) then  FADOQuery:= nil;
    if (AComponent = FDataSource) and (Operation = opRemove) then  FDataSource:= nil;
  end;

  procedure TDBLookUpEdit.SetParent(AParent: TWinControl);
  begin
    inherited SetParent(AParent);
    if FDBGrid <> nil then FDBGrid.Parent := self.Owner as TForm;
  end;

  procedure TDBLookUpEdit.SetBounds(ALeft, ATop, AWidth, AHeight: Integer);
  begin
    inherited;
    if FDBGrid <> nil then
      with FDBGrid do
      begin
        Top:=-Height;
        Left:=-Width;
      end;
  end;

  procedure TDBLookUpEdit.SetRecText(FieldNo: integer);
  begin
    self.SetFocus;
    self.SelectAll;
    if (FADOQuery.Connection <>nil) or (FADOQuery.ConnectionString <>'') then
      if FADOQuery.Active then
        if FADOQuery.RecordCount >0 then
          if FADOQuery.FieldCount>FieldNo then
          begin
            self.Text:=FDBGrid.Fields[FieldNo].Text;
            self.SelectAll;
            self.SetFocus;
          end;
  end;

  procedure TDBLookUpEdit.FDoEnter(Sender: TObject);
  var
    p  :TPoint;
  begin
    P:=self.ClientToParent(point(0,self.Height),(self.Owner as TForm));
    if (FDBGrid.Height+p.y+2)<=(self.Owner as TForm).Height then
    begin
      FDBGrid.Top  :=p.y+2;
    end
    else begin
      FDBGrid.Top  :=p.y-2-self.Height -FDBGrid.Height;
    end;
    FDBGrid.Left :=p.x+2;
    FDBGrid.BringToFront;
    FDBGrid.Visible:=true;
    if self.Text='' then SetRecText(1);
    self.SelectAll;
    if (self.Text<>'') and FADOQuery.Active then
      FADOQuery.Locate(FKeyField, self.text,[lopartialkey]);
  end;

  procedure TDBLookUpEdit.FDoExit(Sender: TObject);
  begin
    if not FDBGrid.Focused then  FDBGrid.Visible:=false;
  end;

  procedure TDBLookUpEdit.DoFDBGridMouseUp(Sender: TObject;
    Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  begin
    SetRecText(1);
    FDBGrid.Visible:=false;
  end;

  procedure TDBLookUpEdit.DoFDBGridKeyDown(Sender: TObject; var Key: Word;
    Shift: TShiftState);
  begin
    if key=13 then
    begin
      SetRecText(1);
      FDBGrid.Visible:=false;
      key:=0;
    end;
  end;

  procedure TDBLookUpEdit.CNCommand(var Message: TWMCommand);
  begin
    case Message.NotifyCode of
      EN_CHANGE:
      begin
        if not FCreating then
          if Assigned(FOnChange) then FOnChange(self);
      end;
      EN_KILLFOCUS:
      begin
        if Assigned(FOnExit) then FOnExit(self);
        FDoExit(self);
      end;
      EN_SETFOCUS:
      begin
        if Assigned(FOnEnter) then FOnEnter(self);
        FDoEnter(self);
      end;
    end;
  end;

  procedure TDBLookUpEdit.DblClick;
  begin
    inherited;
    FDoEnter(self);
  end;

  function TDBLookUpEdit.GetDataSource: TDataSource;
  begin
    Result := FDBGrid.DataSource;
  end;

  procedure TDBLookUpEdit.SetDataSource(Value: TDataSource);
  begin
    if Value <> FDBGrid.Datasource then  FDBGrid.DataSource := Value;
    if Value <> nil then Value.FreeNotification(Self);
  end;

  procedure TDBLookUpEdit.KeyDown(var Key: Word; Shift: TShiftState);
  begin
    inherited;
    if FDBGrid.Visible then
    begin
      if (key=38) or (key=40) then
      begin
        SendMessage(FDBGrid.Handle,WM_KEYDOWN,key,0);
        key:=0;
      end;
      if key=13 then
      begin
        SetRecText(1);
        FDBGrid.Visible:=false;
        key:=0;
      end;
    end;
  end;

  //判斷是否全是數字
  function IsAllInteger(Text:widestring):boolean;
  var
    Temp:string;
    i:integer;
  begin
    try
      Result:=true;
      Temp:=trim(text);
      if (length(Temp)<=0) then
      begin
        Result:=false;
        exit;
      end;
      for i:=1 to length(Temp) do
      begin
        if not (Temp[i] in ['0'..'9']) then
        begin
          Result:=false;
          break;
        end;
      end;
    except
      Result:=false;
    end;
  end;

  //生成篩選語句
  function CSQL(EditText,FieldName:WideString):WideString;
  var
    i:integer;
    sql:WideString;
    tmEditText1,tmEditText2:WideString;
  begin
    Result:='';
    if IsAllInteger(EditText) then
    begin
      tmEditText1:=trim(EditText);
      tmEditText2:=trim(EditText);
      SQL:=SQL+'('+FieldName+'>='+trim(EditText)+' and '+FieldName+'<='+inttostr((StrToInt(EditText) div 10)*10+9)+')';
      for i:=length(EditText) to 6 do
      begin
        tmEditText1:=tmEditText1+'0';
        tmEditText2:=tmEditText2+'9';
        sql:=sql+' or ('+FieldName+'>='+tmEditText1+' and '+FieldName+'<='+tmEditText2+')';
      end;
      Result:=sql;
    end;
  end;

  procedure TDBLookUpEdit.KeyUp(var Key: Word; Shift: TShiftState);
  begin
    inherited;
    if FDBGrid.Visible then
    begin
      if (key=38) or (key=40) then
      begin
        SetRecText(1);
      end
      else if IsAllInteger(self.Text) then
      begin
        FADOQuery.Filtered:=false;
        FADOQuery.Filter:=CSQL(self.Text,FKeyField);
        FADOQuery.Filtered:=true;
      end;
    end;
  end;

  procedure TDBLookUpEdit.KeyPress(var Key: Char);
  begin
    inherited;
  end;

  function TDBLookUpEdit.GetConnection: TADOConnection;
  begin
    Result := FADOQuery.Connection;
  end;

  procedure TDBLookUpEdit.SetConnection(const Value: TADOConnection);
  begin
    if Value <> FADOQuery.Connection then
    begin
      FADOQuery.Connection := Value;
    end;
    if Value <> nil then Value.FreeNotification(Self);
  end;

  function TDBLookUpEdit.GetConnectionString: WideString;
  begin
    Result := FADOQuery.ConnectionString;
  end;

  procedure TDBLookUpEdit.SetConnectionString(const Value: WideString);
  begin
    if Value <> FADOQuery.ConnectionString then  FADOQuery.ConnectionString := Value;
  end;

  function TDBLookUpEdit.GetActive: Boolean;
  begin
    Result :=FADOQuery.Active;
  end;

  procedure TDBLookUpEdit.SetActive(Value: Boolean);
  begin
    if Value <> FADOQuery.Active then
    begin
      FADOQuery.Active := Value;
    end;
  end;

  function TDBLookUpEdit.GetSQL: TStrings;
  begin
    Result := FADOQuery.SQL;
  end;

  procedure TDBLookUpEdit.SetSQL(const Value: TStrings);
  begin
    if FADOQuery.SQL<>Value then FADOQuery.SQL.Assign(Value);
  end;

  procedure TDBLookUpEdit.Loaded;
  begin
    inherited Loaded;
  end;

  end.

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved