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

📄 nbcombobox.pas

📁 比Borland的ComboBox多了个自动搜索中文字符串的功能
💻 PAS
字号:
unit NBComboBox;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;

type
  TExComboBox = class(TComboBox)
  private
    { Private declarations }
    iPreItemIndex:integer;
    strPreKey:string;
    stlMixStrs:TStringList; //ComboBox的英文字符与汉字拼音首字符的混合字符串组
    iChangeCount:integer;   //判断change的次数.
    strInput:string;        //捕捉ComboBox.style=csDropDownList时输入的字符串
    a:integer;
  protected
    { Protected declarations }
    //冒泡排序
    procedure BubbleSort(var stlMixStrings:TStringList);
    //得到字符的ASCII码
    function GetASCII(str:string):integer;
    //把含有中文的字符串转化为含该中文拼音首字符的字符串。
    function AllChiToEng(str:string):string;
    //得到汉字的拼音首字符
    function GetPYIndexChar( hzchar:string):char;
    //覆盖父类OnDropDown事件的派遣方法DropDown.
    procedure DropDown;override;
    //清空用户输入的字符串
    procedure Click;override;
    //初始化iPreItemIndex跟strPreKey.
    procedure DoExit;override;
    //用来捕捉用户输入。
    procedure KeyPress(var Key: Char); override;
  public
    { Public declarations }
    constructor Create(AOwner:TComponent);override;
    destructor Destroy;override;
  published
    { Published declarations }
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('Standard', [TExComboBox]);
end;

constructor TExComboBox.Create(AOwner:TComponent);
begin
   inherited Create(AOwner);
   //self.Style := csDropDownList;
   self.Style := csDropDown;
   strInput := '';
   iPreItemIndex := 0;
   strPreKey := '';
   stlMixStrs := TStringlist.Create;
   iChangeCount := 0;
end;

procedure TExComboBox.DoExit;
begin
   inherited;
   iPreItemIndex := 0;
   strPreKey := '';
end;

destructor TExComboBox.Destroy;
begin
   stlMixStrs.Free;
   inherited Destroy;
end;

procedure TExComboBox.BubbleSort(var stlMixStrings:TStringList);
var
   i,j,iStrCount:integer;
   bNoSwap:boolean; //未交换标志。
   strTemp:string;
begin
   iStrCount := stlMixStrings.Count;
   for i:=0 to (iStrCount-2) do
   begin
      bNoSwap := true;
      //for j:=(iStrCount-2) to i do  //pascal无这种语法,要用while.
      j:=iStrCount-2;
      while j>=i do
      begin
         if ((stlMixStrings.Strings[j+1])<(stlMixStrings.Strings[j])) then
         begin
            //妙!!排拼音首字符顺序的同时改变ComboBox的字符串顺序!
            strTemp := stlMixStrings.Strings[j+1];
            stlMixStrings.Strings[j+1] := stlMixStrings.Strings[j];
            stlMixStrings.Strings[j] := strTemp;
            //bNoSwap := false;
            strTemp := self.Items.Strings[j+1];
            self.Items.Strings[j+1] := self.Items.Strings[j];
            self.Items.Strings[j] := strTemp;
            bNoSwap := false;
            
         end;
         j := j-1;
      end;
      if (bNoSwap) then break;
   end;
end;

function TExComboBox.GetASCII(str:string):integer;
begin
   if str='a' then result:=97
   else if str='b' then result:=98
   else if str='c' then result:=99
   else if str='d' then result:=100
   else if str='e' then result:=101
   else if str='f' then result:=102
   else if str='g' then result:=103
   else if str='h' then result:=104
   else if str='i' then result:=105
   else if str='j' then result:=106
   else if str='k' then result:=107
   else if str='l' then result:=108
   else if str='m' then result:=109
   else if str='n' then result:=110
   else if str='o' then result:=111
   else if str='p' then result:=112
   else if str='q' then result:=113
   else if str='r' then result:=114
   else if str='s' then result:=115
   else if str='t' then result:=116
   else if str='u' then result:=117
   else if str='v' then result:=118
   else if str='w' then result:=119
   else if str='x' then result:=120
   else if str='y' then result:=121
   else if str='z' then result:=122
   else if str=' ' then result:=32
   else if str='!' then result:=33
   else if str='"' then result:=34
   else if str='#' then result:=35
   else if str='$' then result:=36
   else if str='%' then result:=37
   else if str='&' then result:=38
   else if str='''' then result:=39
   else if str='(' then result:=40
   else if str=')' then result:=41
   else if str='*' then result:=42
   else if str='+' then result:=43
   else if str=',' then result:=44
   else if str='-' then result:=45
   else if str='.' then result:=46
   else if str='/' then result:=47
   else if str='0' then result:=48
   else if str='1' then result:=49
   else if str='2' then result:=50
   else if str='3' then result:=51
   else if str='4' then result:=52
   else if str='5' then result:=53
   else if str='6' then result:=54
   else if str='7' then result:=55
   else if str='8' then result:=56
   else if str='9' then result:=57
   else if str=':' then result:=58
   else if str=';' then result:=59
   else if str='<' then result:=60
   else if str='=' then result:=61
   else if str='>' then result:=62
   else if str='?' then result:=63
   else if str='@' then result:=64
   else if str='A' then result:=65
   else if str='B' then result:=66
   else if str='C' then result:=67
   else if str='D' then result:=68
   else if str='E' then result:=69
   else if str='F' then result:=70
   else if str='G' then result:=71
   else if str='H' then result:=72
   else if str='I' then result:=73
   else if str='J' then result:=74
   else if str='K' then result:=75
   else if str='L' then result:=76
   else if str='M' then result:=77
   else if str='N' then result:=78
   else if str='O' then result:=79
   else if str='P' then result:=80
   else if str='Q' then result:=81
   else if str='R' then result:=82
   else if str='S' then result:=83
   else if str='T' then result:=84
   else if str='U' then result:=85
   else if str='V' then result:=86
   else if str='W' then result:=87
   else if str='X' then result:=88
   else if str='Y' then result:=89
   else if str='Z' then result:=90
   else if str='[' then result:=91
   else if str='\' then result:=92
   else if str=']' then result:=93
   else if str='^' then result:=94
   else if str='_' then result:=95
   else if str='`' then result:=96
   else if str='{' then result:=123
   else if str='|' then result:=124
   else if str='}' then result:=125
   else if str='~' then result:=126
   else result := -1;
end;

function TExComboBox.AllChiToEng(str:string):string;
var
   i,iStrLength:integer;
   strPYFirChar:string;
   strMixString:string;  //包含英文字符跟拼音首字符的字符串
   hzChar:string;  //汉字字符
begin

   strMixString := '';
   iStrLength:= Length(str);
   i := 1;
   while i<= iStrLength do
   begin
      if (GetASCII(str[i])=-1) then //第i位置是汉字(应该用str1[i],不能用copy(str1,1,1))。
      begin
         hzChar := str[i]+str[i+1];
         strPYFirChar := GetPYIndexChar(hzChar);
         strMixString:=strMixString+strPYFirChar;
         i := i+2;
      end
      else if (GetASCII(str[i])<>-1) then   //第i位置是英文。
      begin
         strMixString := strMixString+str[i];
         i := i+1;
      end;
   end;
   result := strMixString;
end;

function TExComboBox.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;

procedure TExComboBox.DropDown;
var
   i:integer;
begin
   if iChangeCount=0 then
   begin
      stlMixStrs := TStringList.Create;
      for i:= 0 to self.Items.Count-1 do
      begin
         stlMixStrs.Add(AllChiToEng(self.items.Strings[i]));
      end;
      //冒泡排序stlMixStrs的同时调整的combo字符串的顺序
      BubbleSort(stlMixStrs);
   end;
   inc(iChangeCount);
   inherited;
end;

procedure TExComboBox.KeyPress(var Key: Char);
var
   i,j,CurIndex:integer;
begin
   CurIndex := 0;
   //先给字符串排顺
   if iChangeCount=0 then
   begin
      stlMixStrs := TStringList.Create;
      for i:= 0 to self.Items.Count-1 do
      begin
         stlMixStrs.Add(AllChiToEng(self.items.Strings[i]));
      end;
      //冒泡排序stlMixStrs的同时调整的combo字符串的顺序
      BubbleSort(stlMixStrs);
   end;
   inc(iChangeCount);
   //搜索匹配字符串
   for i:= 0 to self.Items.Count-1 do
   begin
      if copy(stlMixStrs.Strings[i],1,1)=lowercase(char(Key)) then
      begin
         if strPreKey=lowercase(char(Key)) then //本次键入字符跟上次相同,处理循环搜索问题。
         begin
            if i=iPreItemIndex then//搜索上次匹配字符串的下一个匹配字符串。
            begin
               //查看下一字符串匹配否?
               if (i+1)<= self.Items.Count-1 then//禁止下标出界
               begin
                  if copy(stlMixStrs.Strings[i+1],1,1)=lowercase(char(Key)) then//匹配
                  begin
                     self.ItemIndex := i+1;
                     CurIndex := i+1;
                     //当选中若干匹配字符串的最后一个字符串时,
                     //如果strPreKey=lowercase(char(Key)),那么
                     //选中若干匹配字符串的第一个字符串
                     if i+1=self.Items.Count-1 then //考虑最后一个字符串。
                     begin
                        iPreItemIndex := 0;
                        strPreKey := '';
                     end
                     else
                     begin
                        iPreItemIndex := i+1;
                        strPreKey := lowercase(char(Key));
                     end;
                     break;
                  end
                  else   //不匹配。从第一个字符串搜索至i位置。
                  begin
                     for j:= 0 to i do
                     begin
                        if copy(stlMixStrs.Strings[j],1,1)=lowercase(char(Key)) then
                        begin
                           self.ItemIndex := j;
                           CurIndex :=j;
                           iPreItemIndex := j;
                           strPreKey := lowercase(char(Key));
                           break; //跳出内层循环
                        end
                     end;
                  end;
               end;
               break; //跳出外层循环。
            end;
         end
         else  //本次键入字符跟上次不同。
         begin
            self.ItemIndex := i;
            CurIndex := i;
            iPreItemIndex := i;
            strPreKey := lowercase(char(Key));
            break;
         end;
      end;
   end;
   if self.Items.Count > 0 then
        self.Text := self.Items.Strings[CurIndex];
   Key:=char($0); //重点注意:每次键入字符后要清!!!!!!!!!!
   inherited;
end;


procedure TExComboBox.Click;
begin
   inherited;
end;

end.

⌨️ 快捷键说明

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