function Tfrmaddry.GetPYIndexChar(hzchar:string):char;//HZCHAR是单个汉字,
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;

解决方案 »

  1.   

    同意楼上的!!!
    这里有个关于它的使用方法:按拼音检索
    type
      TForm1 = class(TForm)
        Edit1: TEdit;
        ListBox1: TListBox;
        ListBox2: TListBox;
        Label2: TLabel;
        Label1: TLabel;
        procedure Edit1Change(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;var
      Form1: TForm1;implementationfunction GetCharInd(zzchar:string):char;
    begin
      case WORD(zzchar[1]) shl 8+WORD(zzchar[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:=#0;
      end;
    end;function DisByStrInd(ListBoxStr:TListBox;StrInd:string):string;
    label NotFound;
    var
      zzchar :string;
      i,j:integer;
    begin
      for i:=0 to ListBoxStr.Items.Count-1 do
      begin
        for j:=1 to Length(StrInd) do
        begin
          zzchar:=ListBoxStr.Items[i][2*j-1]+ListBoxStr.Items[i][2*j];
          if (StrInd[j]<>'?') and (UpperCase(StrInd[j])<>GetCharInd(zzchar))
          then goto NotFound;
        end;
        if result='' then result:=ListBoxStr.Items[i]
        else result:=result+#13+ListBoxStr.Items[i];
    NotFound:
      end;
    end;{$R *.DFM}procedure TForm1.Edit1Change(Sender: TObject);
    var
      SelStr:string;
    begin
      SelStr:='';
      ListBox2.Items.Text:=DisByStrInd(listBox1,Edit1.Text);
    end;end.
      

  2.   

    function ZsWordStrCnToShort(mStr: string): string; { 返回单个汉字的拼音简码 }
    var
      I: Integer;
    const
      cMinGBCByte = 161;                           //最小国标字节
      cMaxGBCByte = 254;                           //最大国标字节  function f(mStr): Integer;
      begin
        Result := (Ord(mStr[1]) - cMinGBCByte + 1) * 100 + 
          Ord(mStr[2]) - cMinGBCByte + 1
      end;
    begin
      I := f(mStr); //区位码//如果mStr不是一个汉字我可不管
      case I of
        1601..1636:
          Result := 'A';
        1637..1832:
          Result := 'B';
        1833..2078:
          Result := 'C';
        2079..2273:
          Result := 'D';
        2274..2301:
          Result := 'E';
        2302..2432:
          Result := 'F';
        2433..2593:
          Result := 'G';
        2594.. 2786:
          Result := 'H';
        2787..3105:
          Result := 'J';
        3106..3211:
          Result := 'K';
        3212..3471:
          Result := 'L';
        3472..3634:
          Result := 'M';
        3635..3721:
          Result := 'N';
        3722..3729:
          Result := 'O';
        3730..3857:
          Result := 'P';
        3858..4026:
          Result := 'Q';
        4027..4085:
          Result := 'R';
        4086..4389:
          Result := 'S';
        4390..4557:
          Result := 'T';
        4558..4683:
          Result := 'W';
        4694..4924:
          Result := 'X';
        4925..5248:
          Result := 'Y';
        5249..5589:
          Result := 'Z';
      else
        Result := '_';
      end;
    end; { ZsWordStrCnToShort }
      

  3.   

    在心铃之家有个现成的控件
    likepc.51.net
      

  4.   

    没这几位程序中的那么简单吧。
    首先,二级字库中的汉字是按部首笔画排列的。(二级字库?可能很多人没听说过吧。)
    其次,如果是在gbk标准中扩展的汉字,更没这么简单的规律可循。
      

  5.   

    哪个控件基本解决了二级字库的问题,但是GBK还是没有解决
      

  6.   

    to 严黎斌:
      case I of
        //...
        2594 .. 2786, 8032{鹄}:  //自己加
          Result := 'H';
        //...
      else
        Result := '_';
      end;最好的方法是从[全拼]输入法里起
      

  7.   

    to 严黎斌:
      case I of
        //...
        2594 .. 2786, 8032{鹄}:  //自己加
          Result := 'H';
        //...
      else
        Result := '_';
      end;最好的方法是从[全拼]输入法里取
      

  8.   

    to 严黎斌:
      如果是二级字库就自己加一下
    //........
        2594..2786, 8032{鹄}:
          Result := 'H';
    //........
      当然这样会很麻烦,最好的方法还是从[全拼]输入法中取
      

  9.   

    我对csdn的速度忍无可忍了!
    慢点发火,告诉大家更好更妙的做法。
    要真正处理汉字排序问题,还是应该用win2000。
    是这样的,win2000对多种语言的支持非常好了。比如就支持汉字的正确排序。在控制面版中的区域设置中设置好好排序的依据,比如说是拼音还是笔画排序。然后,只要调用其标准的api函数比如lstrcmp,是能返回正确的判断结果的。这包括对原gb2312的一级字库、二级字库的正确处理,对gbk字符集的正确处理。你再也不用为内码排列与需要的次序不一样而担心。
    如果要取汉字的拼音首字母,那也很简单,作个数组,记录26个字母对应的第一个汉字,然后将需要的汉字与这26个汉字比较就可以了。
      

  10.   

    对了,补充两点:
    首先,修改控制面版中的汉字排序设置后,需要重新登录才能起作用。
    其次,delphi将lstrcmp等函数申明在windows.pas文件中,你可直接调用。
    需要功能更多的比较函数,可以使用CompareString
      

  11.   

    同意严黎斌我一年前用Access取得过同样的结论,我把所有可能的汉字插入到一个Access表中,排序一下,发现它们按拼音顺序排列。当然多音字的问题没法简单解决。这个办法充分利用了操作系统的能力,简化了自己的代码,很不错。
      

  12.   

    我用bcb5编了一个dll,85k,可以反查gbk汉字(20902个)的拼音(全拼也可)及五笔首码,
    无须输入法支持,能自动识别单字节字符。不是用“内建字库+比较汉字”的方法,速度极快,有详细说明。想要可e-mail我。
      

  13.   

    不要输入法支持,通过汉字得到拼音和五笔的算法可以实现,但不是一两句话能说清,
    有兴趣的话可以e-mail给我讨论。多音字一般返回“较常用”的那个(没有办法的办法?),再说了,
    一般反查拼音、五笔多用于数据库汉字字段的查询,只要首码即可,
    多音字问题不算太碍事,如“觉”(jiao、jue)首码一样。上面提到的dll文件即是专为此而做的,可以传入汉字字符串(夹杂英文、数字、全角字符都行,可以选择是否过滤掉),返回拼音(完整拼音)、五笔首码串(串长度也可设定),但没有特别地处理多音字,也不太好处理。
      

  14.   

    www.inprises.com可能会对你有帮助
      

  15.   

    >>myy()
    如果有源码,我很愿意得到一份:[email protected]
      

  16.   

    [Description]
    Name=全拼
    MaxCodes=12
    MaxElement=1
    UsedCodes=abcdefghijklmnopqrstuvwxyz
    WildChar=?
    NumRules=3
    [Rule]
    ca4=p10+p20+p30+p40
    ce2=p10+p20
    ce3=p10+p20+p30
    [Text]
    啊a
    阿a
    呵a he
    吖a
    嗄a
    腌a yan
    锕a
    錒a ke
    阿爸aba
    阿昌achang
    把\windows\system\winpy.mb逆转换成.txt文件,格式如上,遍历这个文件,其实就是实现自己的拼音输入法,用拼音查汉字,或汉字查拼音都行,获的头字母简直太简单了。
    \windows\system\imggen.exe 进行转换
      

  17.   

    My god! Are you kidding?
      

  18.   

    同志们哪,怎么整得那么麻烦,你们没注意我前面的帖子嘛?
    在win2000中,调用api函数lstrcmp,什么问题都解决了。不管你是gb2312中的一级、二级字库,还是gbk字库,简体,繁体,都能正确排序,而且还可以由用户选择是按拼音还是笔画排序。
    功能强大、完备,实现起来又异常简单,为啥不用?
      

  19.   

    用CompareString.lstrcmp的比较结果依赖于用户的具体设定,因此有不确定性! 
      

  20.   

    至于反查汉字的拼音编码,以前有讨论的!
    以前的贴子:
    function QueryCompStr(hKB: HKL; const sChinese: AnsiString): string;
    var
      dwGCL: DWORD;
      szBuffer: array[0..254] of char;
      iMaxKey, iStart, i: integer;
    begin
      Result := '';
      iMaxKey := ImmEscape(hKB, 0, IME_ESC_MAX_KEY, nil);
      if iMaxKey <= 0 then exit;  dwGCL := ImmGetConversionList(hKB,0,pchar(sChinese),nil,0,GCL_REVERSECONVERSION);
      if dwGCL <= 0 then Exit;   dwGCL := ImmGetConversionList(hKB,0,pchar(sChinese),@szBuffer,dwGCL,GCL_REVERSECONVERSION);  if dwGCL > 0 then
      begin
        iStart := byte(szBuffer[24]);
        for i := iStart to iStart + iMaxKey * 2 do
          AppendStr(Result, szBuffer[i]);
      end;
    end;但是上面的程序有问题,解决如下:  ------------------------------------------------------------
        在QueryCompStr中做如下修改就好(test in:win98 se+delphi5)
        dwGCL := dwGCL+sizeof(TCandidateList); //add this line then ok,编码查询功能只支持单字,不支持词组。
        dwGCL := ImmGetConversionList(hKB,0,pchar(sChinese),@szBuffer,dwGCL,GCL_REVERSECONVERSION);
      ----------------------------------------------------------------
        按照pqx给我的答案,问题已解决部分,但用这种方法并不是所有的输入法都能查出,而用Windows自已的编码查询功能(右击输入法提示条,设置->编码查询,选择相应的输入法)则都能查出来,这是为什么呢?(如"王码五笔4.0"就查不出,而微软的"王码五笔86版"、"王码五笔98版"则都能查到。)
        反查编码的的例子可以到 http://www.mildragon.com 的"学习园地"下载。本例是改自台湾钱达智先生的一个例子QRYCOMP(可以在Delphi深度历险中下载)。
    *********
    var
      iHandleCount: integer;
      pList: array[1..nHKL_LIST] of HKL;
      szImeName: array[0..254] of char;
      i: integer;
      sFound: string;
    begin
      lstComposition.Items.Clear;
      iHandleCount := GetKeyboardLayoutList(nHKL_LIST, pList);
      for i := 1 to iHandleCount do
      begin
        if ImmEscape(pList[i], 0, IME_ESC_IME_NAME, @szImeName) > 0 then
        begin
          sFound := QueryCompStr(pList[i], edtExam.Text);
          if sFound <> '' then
            lstComposition.Items.Add(StrPas(szImeName) + ': ' + sFound);
        end;
      end;
      

  21.   

    按照getit911(你的Windows蓝屏啦)的方法,把把\windows\system\winpy.mb逆转换成.txt文件,再去掉里面的词组。找出相对应的汉字可以得到汉字的首字拼音,而且多字音也可以啊。
    顺便问一下:要文本文件查找字符时有哪种好得算法?
    如果把文本文件作为字符串资源文件。那么在字符串资源文件中又是如何查找字符呢?