我的开发环境是:windows 2000 server(简体)+delphi 6(简体)+MS SQL server 2000(简体), 但我开发的程式要提供给台湾的一个朋友使用,他们用的是繁体操作系统,输入法也不一样,所以我给他的程式,一运行就全部出现乱码,我应如何做才能解决这个问题呢?

解决方案 »

  1.   

    TO:ycheng(飞狼) 
    具体怎样做呢?
      

  2.   

    我也碰到这样的问题,找了好多资料都没能解决
    好有好的解决方法请E—MAIL给我,谢谢!email:[email protected]
      

  3.   

    我一个朋友是在繁体上开发的,我的简体的系统,TMD,在我机器上所有繁体的字成了乱码。关注中。
      

  4.   

    如果不想改程序,就让你的朋友装个简体中文包吧,要不然就要将你的程序改为支持多语言的,如何实现多语言方法很多,调用ini是其中一种,就是将程序中用到的标题等都写到ini文件中,然后在程序中动态加载。
      

  5.   

    數據庫字符集的問題是可以解決的,界面什麼的就用INI吧.
      

  6.   

    界面必須做成多語言的東西!
    數據要麼用UNICODE,要麼使用
    寫如數據庫應該加標識,然後檢測系統的LocalID,如果是簡體ID就要...,如果繁體ID,就是...,要麼需要 GB2BIG 或者 BIG2GB 其中一個.
      

  7.   

    用ini文件控制简繁体系统的版本
    用Multilzer 这个软件实现简繁体对应的文字
    具体用法上网搜索吧
      

  8.   

    这个是我写的DLL函数,利用的是WINAPI实现的,在WIN2K以上系统下正常使用。
    如果是9X,请去掉LCMapString函数部分,并使用GBK的繁体字符部分,因为9X对UNICODE支持不好,GBK的简体编码无法对应BIG5的编码,这个也属于BIG5编码不全的问题。
    QQ:35166488
    MAIL TO: [email protected] [email protected]
    =====================================================
    unit UserTypes;interface
    uses
    Windows;
    type
      TLanguageType = (LanguageType_Simplified, LanguageType_Traditional);
    implementationend.
    =====================================================
    unit BIG5_GB_Convert;interface
    uses
    UserTypes;
    function WinGBToBIG5(Source, Destination: PChar; iLen: integer; LanguageType: TLanguageType): WordBool; export; stdcall;
    function WinBIG5ToGB(Source, Destination: PChar; iLen: integer; LanguageType: TLanguageType): WordBool; export; stdcall;
    function LCMAPConvert(Source, Destination: PChar; iLen: integer; LanguageType: TLanguageType): WordBool; export; stdcall;implementation
    uses
    Windows,
      SysUtils;function LCMAPConvert(Source, Destination: PChar; iLen: integer; LanguageType: TLanguageType): WordBool;
    var
    iSourceLen: integer;  //需要转换的字符数
      sNew: string;
    begin
    result := false;
    if iLen >= Length(Source) then
      begin
    iSourceLen := length(Source);
       //给sGB_New分配内存
      SetLength(sNew, iSourceLen);
       if LanguageType =  LanguageType_Simplified then
         //转换GB码到GB码简体,使用API函数LCMapString
        LCMapString($0804, LCMAP_SIMPLIFIED_CHINESE, Source, -1, PChar(sNew), iSourceLen)
      else
      //转换Gb码简体到Gb码繁体,使用API函数LCMapString
    LCMapString($0804, LCMAP_TRADITIONAL_CHINESE, Source, -1, PChar(sNew), iSourceLen);
      StrCopy(Destination, PChar(snew));
       result := true;
      end;
    end;function Big5ToGB(sBig5: string; LanguageType: TLanguageType): string;
    var
    wsUnicode: WideString; //Unicode编码的字符
    sGB: AnsiString;  //GB编码的字符
    iLen: integer;  //需要转换的字符数
      sGB_New: string;   //根据标志转换的Gb编码
    begin
    //计算转换的字符数
    iLen := MultiByteToWideChar(950, 0, PChar(sBig5), -1, nil, 0);
      //给wszUnicode分配内存
      SetLength(wsUnicode, iLen);
      //转换Big5码到Unicode码,使用了API函数MultiByteToWideChar
      MultiByteToWideChar(950, MB_COMPOSITE, PChar(sBig5), -1, PWideChar(wsUnicode), Length(wsUnicode));  //计算转换的字符数
      iLen := WideCharToMultiByte (936, 0, PWideChar(wsUnicode), -1, nil, 0, nil, nil);
      //给sGB分配内存
      SetLength(sGB, iLen);
      //转换Unicode码到Gb码,使用API函数WideCharToMultiByte
      WideCharToMultiByte(936, WC_COMPOSITECHECK, PWideChar(wsUnicode), -1, PAnsiChar(sGB), Length(sGB), '?', PBOOL(false)); iLen := length(sGB);
      //给sGB_New分配内存
      SetLength(sGB_New, iLen);
      if LanguageType =  LanguageType_Simplified then
      //转换GB码到GB码简体,使用API函数LCMapString
        LCMapString($0804, LCMAP_SIMPLIFIED_CHINESE, PChar(sGB), -1, PChar(sGB_New), iLen)
      else
      //转换Gb码简体到Gb码繁体,使用API函数LCMapString
    LCMapString($0804, LCMAP_TRADITIONAL_CHINESE, PChar(sGB), -1, PChar(sGB_New), iLen);  Result := sGB_New;
    end;function GBToBig5(sGB: string; LanguageType: TLanguageType): string;
    var
    wsUnicode: WideString; //Unicode编码的字符
    sBig5: AnsiString;  //Big5编码的字符
    iLen: integer;  //需要转换的字符数
      sGB_New: string;   //根据标志转换的Gb编码
    begin
    iLen := length(sGB);
      //给sGB_New分配内存
      SetLength(sGB_New, iLen);
      if LanguageType =  LanguageType_Simplified then
      //转换GB码到GB码简体,使用API函数LCMapString
    LCMapString($0804, LCMAP_SIMPLIFIED_CHINESE, PChar(sGB), -1, PChar(sGB_New), iLen)
      else
      //转换GB码到GB码繁体,使用API函数LCMapString
    LCMapString($0804, LCMAP_TRADITIONAL_CHINESE, PChar(sGB), -1, PChar(sGB_New), iLen); //计算转换的字符数
    iLen := MultiByteToWideChar (936, 0, PChar(sGB_New), -1, nil, 0);
      //给wszUnicode分配内存
      SetLength(wsUnicode, iLen);
      //转换Gb码到Unicode码,使用了API函数MultiByteToWideChar
      MultiByteToWideChar(936, MB_COMPOSITE, PChar(sGB_New), -1, PWideChar(wsUnicode), Length(wsUnicode)); //计算转换的字符数
      iLen := WideCharToMultiByte (950, 0, PWideChar(wsUnicode), -1, nil, 0, nil, nil);
      //给sBig5分配内存
      SetLength(sBig5, iLen);
      //转换Unicode码到Big5码,使用API函数WideCharToMultiByte
      WideCharToMultiByte(950, WC_COMPOSITECHECK, PWideChar(wsUnicode), -1, PAnsiChar(sBig5), Length(sBig5), '?', PBOOL(false));  Result := sBig5;
    end;function WinGBToBIG5(Source, Destination: PChar; iLen: integer; LanguageType: TLanguageType): WordBool;
    var
      sConvert : string;
    begin
    if (iLen >= Length(Source)) and (Length(Source) > 0) then
      begin
    sConvert := GBToBIG5(Source, LanguageType);
        StrCopy(Destination, PChar(sConvert));
       result := true;
      end
      else
        result := false;
    end;function WinBIG5ToGB(Source, Destination: PChar; iLen: integer; LanguageType: TLanguageType): WordBool;
    var
      sConvert : string;
    begin
    if (iLen >= Length(Source)) and (Length(Source) > 0) then
      begin
    sConvert := BIG5ToGB(Source, LanguageType);
        StrCopy(Destination, PChar(sConvert));
       result := true;
      end
      else
        result := false;
    end;
    end.
      

  9.   

    用TntWare主件,就可以写出多语种的软件。
      

  10.   

    最好写多语言的应用程序,界面的所有Caption可以在sql中建一个多语言的表,
    各个列是不同语言,在程序运行时可以通过标示取哪列(取什么语言)就可以了
      

  11.   

    我也正在研究这个问题,涉及到两个方面:
    一、界面中的固定文字
        如Caption之类的,用ini可以解决。二、数据库中的资料
        存储用UniCode,可是把它们抓到前端时,可能是多种语言的、多种版本的windows系统,如简繁英日韩等的win9x/win2000/winxp...。要使这些资料显示出来后是可读的,应该如何做?由于win9x不支持Unicode,先不管它,只考虑win2000及以上的版本。测试时,简体win2000+D7:如果对nvarchar(10)的赋值 N'中华人民共和国',繁体的win2000上抓出来后,仍然是乱码。
        这个才是重点需要解决的问题。
    三、界面中输入的资料
        目前大多数OS中的输入法,应该输入的都是传统字符集中的文字,要转换为Uniocde,再存储到后端SQL中。如何转换?
        各位,大家共同探讨啊,有什么心得一起分享!
      

  12.   

    越来越多的程序使用了多国语言切换,虽然DELPHI自带多语言包的添加和配置, 
    但是那种方法在切换语言时界面会出现闪烁,而且实现起来很麻烦,这里我介绍给大家的是利用INI文件来读取界面的语种文字, 
    用这种方法,不但简单易行,而且在切换的时候不会出现界面的闪烁。 
        我们从一个例子出发,看看怎么实现语言的切换。首先建立一个新工程。放置如上图的组件:     MainMenu1: TMainMenu; 
        File1: TMenuItem; 
        Exit1: TMenuItem; 
        Label1: TLabel; 
        Button1: TButton; 
        CheckBox1: TCheckBox; 
        CheckBox2: TCheckBox; 
        Button2: TButton; 
        Label2: TLabel; 
        ComboBox1: TComboBox; 
        Label3: TLabel; 由于要读取Ini文件,所以在USES中加入声明IniFiles; 
    然后将Button1和Button2的ShowHint属性设置为True; 
    其中我们用ComboBox1来显示可供选择的语言和用来选择语言。 
    我们在程序的目录下编辑如下的Chinese GB.Ini文件: 
    ;/////////////////////////////////////////////////////////////////// 

    ;  翻译的一些规则: 
    ;  翻译前,拷贝 Chinese GB.ini 改名到 yourlanguage.ini 
    ;  仅仅翻译符号'='后的文字 

    [Translations] 

    Label1.Caption  =文字1 
    Label2.Caption  =文字2 
    Label3.Caption  =语言 
    Button1.Caption =按钮1 
    Button2.Caption =按钮2 
    Button1.Hint    =按钮1_提示 
    Button2.Hint    =按钮2_提示 
    CheckBox1.Caption       =复选框1 
    CheckBox2.Caption       =复选框2 
    File1.Caption   =文件 
    Exit1.Caption   =退出 

    [Messages] 
    ;  
    M1      =信息框测试 

    ;////////////////////////////////////////////////////////////////// 
    同样的方法编辑一个名为English.ini的文件,将“=”左边的文字改为英文。 
    例如:Label1.Caption    =Label1 程序运行时,我们查找当前目录下所有的语言配置文件(*.ini), 
    为了达到这个目的, 
    我编写了如下的函数搜索目录下所有的语言配置文件的文件名, 
    然后将文件名去掉ini扩展名保存返回: 
    function TForm1.SearchLanguagePack:TStrings; 
    var 
      ResultStrings:TStrings;        
      DosError:integer; 
      SearchRec:TsearchRec; 
    begin 
      ResultStrings:=TStringList.Create; 
      DosError:=FindFirst(ExtractFilePath(ParamStr(0))+'*.ini', faAnyFile, SearchRec); 
      while DosError=0 do 
      begin 
        { 返回的文件名并去掉末尾的.ini字符 } 
        ResultStrings.Add(ChangeFileExt(SearchRec.Name,'')); 
        DosError:=FindNext(SearchRec); 
      end; 
      FindClose(SearchRec); 
      Result:=ResultStrings; 
    end; 在Form建立的事件中添加代码,将目录下所有的语言文件名加入选择列表框中。 
    procedure TForm1.FormCreate(Sender: TObject); 
    begin 
      ComboBox1.Items.AddStrings(SearchLanguagePack); 
    end; 程序的重点在如何切换语言,在ComboBox1的OnChange事件中进行切换操作。 
    这里我写了SetActiveLanguage过程用于实现这一操作。 
    procedure TForm1.ComboBox1Change(Sender: TObject); 
    begin 
      SetActiveLanguage(ComboBox1.Text); 
    end; 
    其中SetActiveLanguage代码如下: 
    procedure TForm1.SetActiveLanguage(LanguageName:string); 
    const 
      Translations='Translations'; 
      Messages='Messages'; 
    var 
      frmComponent:TComponent; 
      i:Integer; 
    begin 
      with TInifile.Create(ExtractFilePath(ParamStr(0))+LanguageName+'.ini') do 
      begin 
        for i:=0 to ComponentCount-1 do { 遍历Form组件 } 
        begin 
          frmComponent:=Components[i]; 
          if frmComponent is TLabel then { 如果组件为TLabel型则当作TLabel处理,以下同 } 
          begin 
            (frmComponent as TLabel).Caption:= 
            ReadString(Translations,frmComponent.Name 
              +'.Caption',(frmComponent as TLabel).Caption); 
          end; 
          if frmComponent is TCheckBox then 
          begin 
            (frmComponent as TCheckBox).Caption:= 
            ReadString(Translations,frmComponent.Name 
              +'.Caption',(frmComponent as TCheckBox).Caption);         
          end; 
          if frmComponent is TButton then 
          begin 
            (frmComponent as TButton).Caption:= 
            ReadString(Translations,frmComponent.Name 
              +'.Caption',(frmComponent as TButton).Caption); 
            (frmComponent as TButton).Hint:= 
            ReadString(Translations,frmComponent.Name 
              +'.Hint',(frmComponent as TButton).Hint); 
          end; 
          if frmComponent is TMenuItem then 
          begin 
            (frmComponent as TMenuItem).Caption:= 
            ReadString(Translations,frmComponent.Name 
              +'.Caption',(frmComponent as TMenuItem).Caption); 
          end; 
        end; 
        M1:=ReadString(Messages,'M1',M1); 
      end; 
    end; 
    在这个过程中,我们遍历了Form中的所有组件, 
    根据他们的类别和组件名动态的从ini配置文件中读出应该显示的语言文字。 
    用遍历组件的方法比一个一个写出具体的组件维护起来要方便很多,代码的适应性也更强。 
    其中M1为一个字符串变量,这样提示消息也能切换,比如在Button1的Click事件中 
    procedure TForm1.Button1Click(Sender: TObject); 
    begin 
      ShowMessage(M1); 
    end; 
    就可以根据不同的语言给出不同的提示文字。 好了,整个工程就做完了,你可以运行测试一下,是不是切换迅速而且无闪烁。