我们单位用的两个软件,都有用“拼音快速带出汉字”的功能。一个是用“一个Edit和一个DBGrids”从数据库中调数据实现;另一个是用“一个DBComboBox”动态从一个文本文件中调数据实现。前一种方法很容易做到就不说了,后一种方法简单明了非常好,但我费了很大的劲都实现不了。关键是在编辑框中输入拼音时,下拉框中被选择的数据马上就会进入到编辑框中,不能实现拼音的连续输入。借鉴一个网友的想法,我用两个ComboBox实现了“拼音/汉字 快速带出汉字”这一功能。做法是用combobox1 完全盖住combobox2(这样看起来和一个一样),然后设它们的autocomplete属性为false(因其自带的带出汉字的功能不太好,所以完全自己做)。文本文件xx.txt的格式是:
北京市 bjs (汉字后跟一个空格)
北京大学 bjdx
北京科技大学 bjkjdx
北京动物园 bjdwy下面是源代码。有不对的地方望高手指点(我可是个菜鸟),有能用一个combobox实现这一功能的,望贴出来大家共享一下。
var
  Form1: TForm1;
  py:array[0..300] of string;  //这个数组用来存放对应汉字的拼音implementation{$R *.dfm}function IsEnCase(Vaule:String):boolean; //判断Vaule 是不是字母
var
  i:integer;
begin
  result:=false; //设置返回值为 否
  Vaule:=trim(Vaule); //去空格
  for i:=1 to length(Vaule) do //准备循环
  begin
    if (Vaule[i] in ['A'..'Z']) or//如果Vaule的第i个字是A-Z
       (Vaule[i] in ['a'..'z']) then //或者a-z中的任一个
    begin
      result:=true; //返回值 是
      exit; //退出函数
    end;
  end;
end;procedure TForm1.FormShow(Sender: TObject);
var
  f:textfile;  //文件变量
  s:widestring;  //存放文本文件的一行数据
  s1:widestring;  //存放汉字
  s2:widestring;  //存放拼音
  i:integer;
begin
  assignfile(f,'j:\yy\xx.txt');  //将文件变量关联到磁盘中的文本文件
  i:=0;
  try
    reset(f);
    try
      while not eof(f) do  //如果不到结尾处就循环下去
      begin
        readln(f,s);
        s1:=copy(s,1,pos(' ',s)-1);  //取出汉字
        s2:=copy(s,pos(' ',s)+1,length(s));  //取出拼音
        combobox1.Items.Add(s1);  //将汉字读到Items中
        combobox2.Items.Add(s1);
        py[i]:=s2;  //将拼音读到数组py中
        Inc(i);  //加一后再取文本文件下一行数据
      end;
      finally
        closefile(f);  //关闭文件
    end;
  except
    showmessage('读取文件错误!');
  end;
end;procedure TForm1.ComboBox1Change(Sender: TObject);
var
  s:string;
  j:integer;
begin
  s:=combobox1.Text;
  if combobox1.Text='' then
  begin
    combobox2.DroppedDown:=false;
    combobox2.Text:='';
  end;
  if IsEnCase(s)=true then  //如果输入的是拼音
  begin
    for j:=0 to combobox1.Items.Count-1 do
    begin
      if pos(s,py[j])=1 then  //如果在拼音数组中找到匹配的数据
      begin
        combobox2.DroppedDown:=true;  //combobox2的下拉框展开
        combobox2.ItemIndex:=j;  //第j行被选择
        break;  //结束循环
      end
      else
        combobox2.DroppedDown:=false;
    end;
  end
  else    //如果输入的不是拼音(大部分应该是汉字了)
    for j:=0 to combobox1.Items.Count-1 do
    begin
      if pos(s,combobox1.Items[j])=1 then  //如果在combobox1的items中找到匹配的数据
      begin
        combobox2.DroppedDown:=true;
        combobox2.ItemIndex:=j;
        break;
      end
      else
        combobox2.DroppedDown:=false;
    end;
end;procedure TForm1.ComboBox1KeyPress(Sender: TObject; var Key: Char);
begin
  if (key=#13) and (combobox1.Text<>'') then //如果按下的是回车键
  begin
    combobox1.Text:=combobox2.Text;
    combobox1.SelectAll;
    combobox2.DroppedDown:=false;
  end;end;procedure TForm1.ComboBox1Select(Sender: TObject);
begin
  combobox1.DroppedDown:=false;
  combobox2.Text:=combobox1.Text;
end;procedure TForm1.ComboBox2Select(Sender: TObject);
begin
  combobox1.Text:=combobox2.Text;
end;

解决方案 »

  1.   

    感觉你写的代码有点罗嗦了这是一点代码,实现汉字拼音的模糊查询,我用的listbox显示,原理跟dagrid差不错
      

  2.   

    // 获取指定汉字的拼音索引字母,如:“汉”的索引字母是“H”
    function TForm1.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;// 在指定的字符串列表SourceStrs中检索符合拼音索引字符串PYIndexStr的所有字符串,并返回。
    function TForm1.SearchByPYIndexStr( SourceStrs:TStrings; PYIndexStr:string):string;
    label NotFound;
    var
      i, j   :integer;
      hzchar :string;
    begin
      for i:=0 to SourceStrs.Count-1 do
        begin
          for j:=1 to Length(PYIndexStr) do
            begin
              hzchar:=SourceStrs[i][2*j-1]+ SourceStrs[i][2*j];
              if (PYIndexStr[j]<>'?') and (UpperCase(PYIndexStr[j]) <>  GetPYIndexChar(hzchar)) then
              goto NotFound;
            end;
          if result='' then
            result := SourceStrs[i]
          else
            result := result + Char(13) + SourceStrs[i];
            NotFound:
        end;
    end;procedure TForm1.FormCreate(Sender: TObject);
    begin
      SourceLst.Items.LoadFromFile(ExtractFilePath(Application.ExeName) + '检索的数据.txt');
    end;procedure TForm1.EdtSearchChange(Sender: TObject);
    var
      ResultStr:string;
    begin
      ResultStr:=''; //无用字符串
      ResultLst.Items.Text := SearchByPYIndexStr(SourceLst.Items, EdtSearch.Text);
    end;
      

  3.   

    3楼的是又一种方法,也是可行的,只是有点太占地方。
    要是在一个窗体上需要有10以上的box ,那List显然就不行了。
    我们单位用的一个软件,恰恰就用了10多个ComboBox。
    希望大家发贴讨论啊。
    我发个那个并不完美,我已经发现点小不足。并且我发现ComboBox和DBComboBox
    并不完全一样,其中DBComboBox没有OnSelect事件,那我发的那个就更有问题啦。