📄 pycombobox.~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 + -