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

📄 pycombobox.~pas

📁 Delphi控件源码EjunPYComboBox.rarhenhaoyong o
💻 ~PAS
字号:
{*******************************************************}
{                                                       }
{       PYComboBox                                      }
{                                                       }
{       版权所有 (C) 2006 Ejun软件工作室                }
{                                                       }
{       http://www.ejun.cn                              }
{*******************************************************}

unit PYComboBox;

interface

uses
  Windows, Messages, SysUtils, Classes, Controls, StdCtrls, DB, DBCtrls;

type

  TCustomPYComboBox = class(TCustomComboBox)
  private
    FPYListValid: Boolean;
    FPYList: TStringList;
    FSaveItems: TStringList;
    FPYSearching: Boolean;
    procedure CNCommand(var Message: TWMCommand); message CN_COMMAND;
  protected
    procedure ItemsChanged(Sender: TObject); virtual;
    procedure UpdatePYList;  
    function GetItemsClass: TCustomComboBoxStringsClass; override;
    procedure CloseUp; override;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  end;

  TPYComboBoxStrings = class(TCustomComboBoxStrings)
  private
    FOnChange: TNotifyEvent;
  public
    function Add(const S: string): Integer; override;
    procedure Insert(Index: Integer; const S: string); override;
    property OnChange: TNotifyEvent read FOnChange write FOnChange;
  end;

  TPYComboBox = class(TCustomPYComboBox)
  published
    published
    property Style; {Must be published before Items}
    property Anchors;
    property BiDiMode;
    property CharCase;
    property Color;
    property Constraints;
    property Ctl3D;
    property DragCursor;
    property DragKind;
    property DragMode;
    property DropDownCount;
    property Enabled;
    property Font;
    property ImeMode;
    property ImeName;
    property ItemHeight;
    property ItemIndex default -1;
    property MaxLength;
    property ParentBiDiMode;
    property ParentColor;
    property ParentCtl3D;
    property ParentFont;
    property ParentShowHint;
    property PopupMenu;
    property ShowHint;
    property Sorted;
    property TabOrder;
    property TabStop;
    property Text;
    property Visible;
    property OnChange;
    property OnClick;
    property OnCloseUp;
    property OnContextPopup;
    property OnDblClick;
    property OnDragDrop;
    property OnDragOver;
    property OnDrawItem;
    property OnDropDown;
    property OnEndDock;
    property OnEndDrag;
    property OnEnter;
    property OnExit;
    property OnKeyDown;
    property OnKeyPress;
    property OnKeyUp;
    property OnMeasureItem;
    property OnSelect;
    property OnStartDock;
    property OnStartDrag;
    property Items; { Must be published after OnMeasureItem }
  end;

  TDBPYComboBox = class;

  TDBPYComboBox = class(TPYComboBox)
  private
    FDataLink: TFieldDataLink;
    function GetDataSource: TDataSource;
    procedure SetDataSource(const Value: TDataSource);
    function GetDataField: string;
    procedure SetDataField(const Value: string);
    
    procedure DataChange(Sender: TObject);
    procedure ActiveChange(Sender: TObject);
  protected
    procedure Notification(AComponent: TComponent; Operation: TOperation); override;
    procedure Click; override;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  published
    property DataSource: TDataSource read GetDataSource write SetDataSource;
    property DataField: string read GetDataField write SetDataField;
  end;

procedure Register;

implementation

uses
  Consts, Math;

procedure Register;
begin
  RegisterComponents('EjunExpress', [TPYComboBox, TDBPYComboBox]);
end;

function GetPYIndexChar(hzchar:string):char;
begin
  case WORD(hzchar[1]) shl 8 + WORD(hzchar[2]) of
    $B0A1..$B0C4 : result := 'A';
    $B0C5..$B2C0 : result := 'B';
    $B2C1..$B4ED : result := 'C';
    $B4EE..$B6E9 : result := 'D';
    $B6EA..$B7A1 : result := 'E';
    $B7A2..$B8C0 : result := 'F';
    $B8C1..$B9FD : result := 'G';
    $B9FE..$BBF6 : result := 'H';
    $BBF7..$BFA5 : result := 'J';
    $BFA6..$C0AB : result := 'K';
    $C0AC..$C2E7 : result := 'L';
    $C2E8..$C4C2 : result := 'M';
    $C4C3..$C5B5 : result := 'N';
    $C5B6..$C5BD : result := 'O';
    $C5BE..$C6D9 : result := 'P';
    $C6DA..$C8BA : result := 'Q';
    $C8BB..$C8F5 : result := 'R';
    $C8F6..$CBF9 : result := 'S';
    $CBFA..$CDD9 : result := 'T';
    $CDDA..$CEF3 : result := 'W';
    $CEF4..$D188 : result := 'X';
    $D1B9..$D4D0 : result := 'Y';
    $D4D1..$D7F9 : result := 'Z';
  else
    result := char(0);
  end;
end;

// 获取汉字字符串的拼音首写字母组成的字符串
// 注意输入的字符串必须是汉字,否则会出错
function GetFirstPYStr(AHZStr: string): string;
var
  I: Integer;
  hzChar: string;
begin
  Result := '';
  for I:=1 to Length(AHZStr) div 2 do
  begin
    hzchar:=AHZStr[2* I - 1] + AHZStr[2 * I];
    Result := Result + GetPYIndexChar(hzchar);
  end;
end;

procedure TCustomPYComboBox.CloseUp;
var
  SaveItemText: string;
begin
  if FPYSearching then
  begin
    SaveItemText := Items[ItemIndex];
    Items.BeginUpdate;
    Items.Assign(FSaveItems);
    Items.EndUpdate;
    ItemIndex := Items.IndexOf(SaveItemText);
    FPYSearching := False;
  end;
  inherited;
end;

procedure TCustomPYComboBox.CNCommand(var Message: TWMCommand);
  function FilterItems(const PYStr: String): Boolean;
  var
    I: Integer;
  begin
    FPYListValid := False;
    UpdatePYList;
    Items.BeginUpdate;
    try
      // 删除下拉框中的所有项目
      for I := ItemCount - 1 downto 0 do
        SendMessage(Handle, CB_DELETESTRING, I, 0);

      // 添加拼音字符串匹配的项目
      for I := 0 to FPYList.Count - 1 do
        if SameText(Copy(FPYList[I], 1, Length(PYStr)), PYStr) then
        begin
          Items.Add(FSaveItems[I]);
        end;
    finally
      Items.EndUpdate;
    end;
  end;
begin
  if Message.NotifyCode = CBN_EDITCHANGE then
  begin
    if not FPYSearching then
    begin
      FSaveItems.Assign(Items);
      FPYSearching := True;
    end;
    if not DroppedDown then
      DroppedDown := True;
    
    // 过滤下拉框中要显示的项目
    FilterItems(Text);
  end;
  inherited;  
end;

constructor TCustomPYComboBox.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FSaveItems := TStringList.Create;
  FPYList := TStringList.Create;
  FPYList.CaseSensitive := False;
  ItemHeight := 16;
  TPYComboBoxStrings(Items).OnChange := ItemsChanged;
  AutoComplete := False;
  AutoSize := False;
  Text := '';
  MessageBox(0, '您使用的是演示版,请购买正式版', '未注册', MB_OK or MB_ICONINFORMATION);
end;

destructor TCustomPYComboBox.Destroy;
begin
  inherited;
  FPYList.Free;
  FSaveItems.Free;
end;

function TCustomPYComboBox.GetItemsClass: TCustomComboBoxStringsClass;
begin
  Result := TPYComboBoxStrings;
end;

procedure TCustomPYComboBox.ItemsChanged(Sender: TObject);
begin
  FPYListValid := False;
end;

procedure TCustomPYComboBox.UpdatePYList;
var
  I: Integer;
begin
  if not FPYListValid then
  begin
    FPYList.Clear;
    for I := 0 to FSaveItems.Count - 1 do
      FPYList.AddObject(GetFirstPYStr(FSaveItems[I]), TObject(I));
  end;
end;

{ TPYComboBoxStrings }

function TPYComboBoxStrings.Add(const S: string): Integer;
begin
  Result := SendMessage(ComboBox.Handle, CB_ADDSTRING, 0, Longint(PChar(S)));
  if Result < 0 then
    raise EOutOfResources.Create(SInsertLineError);
  if Assigned(FOnChange) then FOnChange(Self);
end;

procedure TPYComboBoxStrings.Insert(Index: Integer; const S: string);
begin
  if SendMessage(ComboBox.Handle, CB_INSERTSTRING, Index,
    Longint(PChar(S))) < 0 then
    raise EOutOfResources.Create(SInsertLineError);
  if Assigned(FOnChange) then FOnChange(Self);
end;

procedure TDBPYComboBox.ActiveChange(Sender: TObject);
var
  sBookmark: string;
begin
  Clear;
  if (DataField = '') or (not FDataLink.Active) then Exit;
  with FDataLink do
  begin
    DataSet.DisableControls;
    try
      sBookmark := DataSet.Bookmark;

      DataSet.First;
      while not DataSet.Eof do
      begin
        Items.Add(FDataLink.Field.AsString);

        if Items.Count > 10 then Exit;

        DataSet.Next;
      end;
    finally
      DataSet.Bookmark := sBookmark; 
      DataSet.EnableControls;
    end;
  end;
end;

procedure TDBPYComboBox.Click;
begin
  if FDataLink.Active then
    FDataLink.DataSet.Locate(DataField, Text, []); 
  inherited;
end;

constructor TDBPYComboBox.Create(AOwner: TComponent);
begin
  inherited;
  FDataLink := TFieldDataLink.Create;
  FDataLink.Control := Self;
  FDataLink.OnActiveChange := ActiveChange;
  FDataLink.OnDataChange := DataChange; 
end;

procedure TDBPYComboBox.DataChange(Sender: TObject);
begin
  ItemIndex := Items.IndexOf(FDataLink.Field.AsString); 
end;

destructor TDBPYComboBox.Destroy;
begin
  FDataLink.Free;
  inherited;
end;

function TDBPYComboBox.GetDataField: string;
begin
  Result := FDataLink.FieldName;
end;

function TDBPYComboBox.GetDataSource: TDataSource;
begin
  Result := FDataLink.DataSource;
end;

procedure TDBPYComboBox.Notification(AComponent: TComponent; Operation:
    TOperation);
begin
  inherited;
  if (Operation = opRemove) and (FDataLink <> nil) and
    (AComponent = DataSource) then DataSource := nil;
end;

procedure TDBPYComboBox.SetDataField(const Value: string);
begin
  FDataLink.FieldName := Value;
  ActiveChange(FDataLink);
end;

procedure TDBPYComboBox.SetDataSource(const Value: TDataSource);
begin
  FDataLink.DataSource := Value;
end;

end.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -