ccidnet????

出版日期:2000-10-01 总期号:164 本年期号:10

本期导读
新闻专递
方案设计
应用篇
技术篇
产品篇
英文Windows 95/98环境下应用软件中汉字的显示与输入

张宇铮、郭宝兰

  自从Microsoft公司针对中国用户专门发布了Windows 95/98等中文版操作系统后,汉字的显示及输入不再是困扰中国计算机使用者的难题,但如何使一个中文应用软件能够在英文版Windows 95/98操作环境下运行并正确显示与输入,是每一个需要推向国外市场的中国软件需要解决的问题,本文就此问题给出了一个简便的解决方案。


  一、无国界的字符编码标准----Unicode


  计算机最早使用的字符编码标准ASCII码是8位码,所包含的字符集仅为128个,这对于西方以字母为基础的文字来说是足够的,但对于象汉语这种表意文字,ASCII码具有太大的局限性。为解决本国文字在计算机内的表示问题,不同的国家分别设计使用了各自的字符编码标准,如我国的GB2312码。但这种不统一的编码标准,造成了软件应用的局限性。为解决这一问题,ISO组织公布了一种通用的、国际的编码标准Unicode。该编码标准采用的是16-bit编码方案,能够区分65536个不同的字符,可以将当今世界上所有的语言文字、符号包含进去,并且留有可供扩展的空间。在Unicode中,每一个字符仅有唯一的一个代码,这保证了语言编码之间可以相互转换。


  二、Windows 95/98对Unicode的支持


  目前,Microsoft公司发布的Windows NT是将Unicode作为内部编码标准的,系统中使用的每一字符串,比如路径名、文件名等都是用16位表示的。但Windows 95/98没有把Unicode作为内部编码标准,严格的说是不支持Unicode代码的平台,但Windows 95/98提供了几个支持Unicode应用的接口函数,如支持显示Unicode字符的TextOutW,ExtTextOutW函数,以及将Unicode字符与其他编码字符进行相互转换的函数WideCharToMultiByte,MultiByteToWideChar等。通过使用这几个函数,可以在英文Windows 95/98平台上,实现应用软件中汉字的正确显示与输入。


  三、英文Windows 95/98环境下应用程序中汉字的显示


  一个在Windows 95/98中文版环境下运行的中文软件,不做任何修改就运行于英文环境下,必将出现汉字不能正确显示的问题,为解决这个问题,应该进行如下几个步骤的工作。

  1.对原程序进行必要的修改

  将原程序中所有显示输出汉字的操作改为由TextOutW函数完成。由于在Windows 95/98中文版中,汉字字符的编码使用的是GBK码,而在英文环境下没有解释此种编码的相关程序,因此即使在英文环境下安装了汉字字库,也不能正确显示汉字。而英文环境下的显示输出函数TextOutW却能识别解释以Unicode编码的汉字,所以为完成正确显示的任务,应将所有需要显示输出的汉字的GBK码转换为Unicode 码,再由TextOutW函数完成显示输出。具体程序段如下:

  CClientDC dc(this);

  chartempstr[100];

  LPWSTR u_tempstr;//指向Unicode代码存储区的指针

  intu_length,y_len;

  u_tempstr=new WCHAR[100]; //申请存储Unicode代码的存储区

  LOGFONTlf;

  HFONThfont;

  strcpy(lf.lfFaceName,"SimSun");//使用SimSun汉字库

  lf.lfCharSet=GB2312_CHARSET; //字符集为GB2312

  lf.lfHeight=12;

  lf.lfWidth=8;

  lf.lfItalic=FALSE;

  lf.lfEscapement=0;

  lf.lfOrientation=0;

  lf.lfWeight=100;

  lf.lfUnderline=FALSE;

  lf.lfStrikeOut=FALSE;

  hfont=CreateFontIndirect(&lf);

  SelectObject(dc.m_hDC,hfont);

  //上面这一段为定义字体

  dc.SetBkColor(RGB(192,192,192));

  strcpy(tempstr,"请输入文件名(不加后缀)"); //需要输出的汉字提示

  y_len=strlen(tempstr);

  u_length=MultiByteToWideChar(936,0,tempstr,y_len,u_tempstr,100);

   //将GBK汉字码转换为Unicode码。函数中第一个参数936为Microsoft定义的码页(Code Page),代表中文汉字。

  TextOutW(dc.m_hDC,16,16,u_tempstr,u_length); //显示输出

  需要说明的是,原程序中由对话框、按钮等类控制输出的汉字,应编写类似上面的程序段将显示输出工作进行接管,否则对话框、按钮等中的汉字将不能正常显示。

  2.安装汉字库

  将Windows 95/98中文版下的汉字库拷贝安装在英文Windows 95/98下。Windows 95/98中文版下的TTF格式汉字库是支持Unicode编码的。

  3.安装必要的汉语言支持模块

  将Windows 95/98中文版本下的汉语言支持模块Cp_936.nls拷贝至英文版Windows 95/98的系统目录下,如:\windows\system目录。修改注册表,在主键HKEY_LOCAL_MACHINE下查询子键codepage,并在该codepage键中加入如下值,936:Cp_936.nls。

  完成以上工作后,将修改后的软件进行编译,产生的可执行文件,在英文环境下就能正确显示汉字了。


  四、英文Windows 95/98环境下应用程序中汉字的输入


  在Windows 95/98中文版中,对汉字输入的支持是做为系统的底层功能而被溶入操作系统中的,系统提供了在任何状态下随时输入汉字的支持。而在英文版Windows 95/98中,从操作系统外部做到这一点几乎是不可能的。因此,当应用软件需要输入汉字时,须直接由应用程序自身提供对汉字输入的支持。具体做法如下:

  1.建立输入汉字字表库及拼音索引表

  在中文版Windows 95/98下,将应用程序中需要输入的汉字按拼音排序,并以一定的结构组织为一个汉字字表库,对该字表库按拼音进行索引建立拼音索引表。库与表的建立是为了实现按全拼法输入汉字,库的结构可根据所提供的具体输入方法而设计。例如:

  字表库可设计为:

  char chinese_table[a][b];//每行中存储注音相同的字,一行十个字

  索引表可设计为:

  structindex {

  charpinyin[7];

  intline_n; //索引chinese_table中的行号

  } index_char[c];

  将建立好的汉字字表库、及拼音索引表拷贝到英文版Windows 95/98机器上,以备使用。

  2.汉字输入界面的设计

  由于输入汉字的部件需要与接收汉字的部件进行交互,故将输入部件的界面,设计为无模式对话框的形式。具体做法是,在应用程序中设计一个命令按钮,触发该按钮将打开汉字输入无模式对话框,在该对话框中放置一个编辑框用于接收并显示键盘输入的汉语拼音,根据键盘输入的拼音通过拼音索引表,查找汉字字表库中相应读音的字组,用TextOutW函数在对话框中进行输出显示,以便用户选择。根据键盘输入的选字编号0-9,将被选中的汉字进行存储,并发送消息给接受汉字的部件。有关程序段如下:

  void Cinput::OnChangeEdit1() //编辑框中有输入即触发该函数

  {

  intma_length,char_number;

  charc_input;

  

  i=0;

  UpdateData(TRUE); //读取键盘输入

  char_number=m_input.GetLength(); //m_input为编辑框变量

  if (char_number>0)

  {

  c_input=m_input.GetAt(char_number-1);

  }

  

  if (c_input==' ') //空格的输入表示完整的拼音已输完,

  {需要将相应读音的汉字组进行显示

  m_input.SetAt(char_number-1,'\0');

  for (;i
  {

  if (strcmp(index_m[i].pinyin,m_input)==0)

  {

  ma_index=index_m[i].line_n;

  strcpy(gb_buffer,mabuffer[ma_index]);

  ma_length=strlen(gb_buffer);

   w_length=MultiByteToWideChar(936,

   0,gb_buffer,ma_length,lptar,100);

  Invalidate();

  break;

  }

  }

  return;

  }

  

  if (c_input>='0' && c_input<='9')

  {

  intfoot;

  

  foot=atoi(&c_input);

  if (foot==0) foot=10;

  m_input.SetAt(0,'\0');

  out_char[i_count]=lptar[foot*4-1];

  lptar[0]='\0';

  gb_input_char[i_count*2-code_num]=gb_buffer[foot*5-2];

  gb_input_char[i_count*2-code_num+1]=gb_buffer[foot*5-1];

  gb_input_char[i_count*2-code_num+2]='\0';

  i_count++;

  w_length=1;

  UpdateData(FALSE);

  Invalidate();

  

  p_Propety->SendMessage(IDC_DISPLAY);

  return;

  } //记忆选定的字,并发送消息给接受部件

  }

  

  以上所介绍的在英文版Windows 95/98环境下,应用程序中实现汉字的显示及输入的方法,已在《本草纲目》电子版中得到应用,且效果良好。实践证明以上所介绍的方案是可行的。本应用软件的编程环境是VC++6.0。