btob郑镒勋:VFP下汉字输入法

来源:百度文库 编辑:中财网 时间:2024/03/29 09:02:34
Windows 应用程序的中西文输入界面中,中、西文的录入需要手工在汉字输入与西文输入之间来回切换,使用起来非常繁琐。针对这一问题,在开发软件时,可以在程序中设置一下拉选择框,让用户自己选择其喜欢的汉字输入法,并且在中文录入框中让程序自动设置用户喜欢的输入法,纯西文、数字输入的地方,让程序自动切换成西文状态。这样,用户在进行中西文录入时,根本不需要手工进行中、西文的来回切换,只管在相应的地方进行录入即可,实现了中西文输入的智能识别。

  本文设计环境为VFP6.0,中文Windows 98。

一、实现方法

  要实现以上功能,需利用Windows API 注册表方面的函数打开系统的注册表以获得当前用户可使用的汉字输入法的名称,将其放入VFP 6.0 表单中的下拉框中供用户选择;同时还需要获得用于打开汉字输入法的句柄;再利用获得的句柄及API 有关打开汉字输入法的功能调用,在相应位置将用户选择的汉字输入法打开;在西文输入的地方利用VFP 6.0 本身的IMESTATUS(0)函数将汉字输入法关闭即可。
  1. 获得当前用户可使用的汉字输入法名称

  ⑴注册表HKEY_LOCAL_MACHINE -->System -->ControlCurrentSet -->Control -->

  -->Keyboard Layouts 下包含Windows 系统支持的所有键盘布局及汉字输入法所对应的主键,如:"E200804"1,在其每一个中都对应着Layout Text 子键,而其值为此种键盘布局或汉字输入法的名称,如" 幸福五笔"。

  ⑵注册表中HKEY_CURRENT_USER ->Keyboard Layout -->Preload 中包含当前用户可使用的汉字输入法所对应的子键,而其键值正对应1 中的健名。

  ⑶利用VFP 6.0 自身带的"registry.prg" 对系统的注册表进行操作。VFP 6.0 的"registry.prg" 通过调用系统的API 函数给我们提供了对系统注册表进行操作的类函数,利用其提供的函数可对系统的注册表进行各种操作,首先到HKEY_CURRENT_USER ->Keyboard Layout -->Preload 中获得当前用户可使用的全部汉字输入法的个数及其所对应的8 位16 进制字符串,而此字符串的十进制形式正是用以打开某一汉字输入法所需要的句柄,再利用已获得的键名1 到注册表HKEY_LOCAL_MACHINE -->System -->ControlCurrentSet -->Control -->Keyboard Layouts -->Layout text 中查找所对应的汉字输入法的中文名称。

  2. 激活用户所选择的汉字输入法

  VFP 本身并没有提供激活某一汉字输入法的程序接口,必须利用WIN32 的API 函数ActivateKeyboardLayout (HKL hkl,UINT Flags),其中hkl 为某种汉字输入法的句柄,Flags 为输入法如何激活的标记,可以为"KLF_REORDER"、"KLF_SETFORPROCESS"、"KLF_UNLOADPREVIOUS"、"KLF_ACTIVATE",在程序中我们选择"KLF_ACTIVATE" 即可。

二、编程实现

  笔者通过在Form 下放置一标签及下拉组合框,同时放置了四个Label、二个Edit 、一个ComboBox、Memo 及Button 为例进行编程说明:
  1. 在VFP 中建立一新的表单form1

  在VFP 中选择" 文件(F)" 菜单下的" 新建(N)",然后选定" 表单(F)",单击" 新建" 按钮,生成一新的表单form1, 设定form1 的属性caption。

   Caption=" VFP 下输入法编程示例"

       Autocenter=.T.
   在FORM1 的init 事件中写入以下代码:

SET PROC TO "C:\Program
Files\Microsoft Visual Studio\msdn98\98vs
\1033\;samples\vfp98\Classes\registry.PRG"
#DEFINE HKEY_CURRENT_USER
-2147483647  &&BITSET(0,31) +1
#DEFINE HKEY_LOCAL_MACHINE  
-2147483646  &&BITSET(0,31) +2
DECLARE INTEGER ActivateKeyboardLayout
  in win32api integer hkl,string flag; addi
public handle,tnumber
private I,cvalue
dime aregopts[1]
cvalue=''
i=1
frmMyForm = CREATEOBJECT("registry")
frmMyForm.init()
frmMyForm.EnumOptions(@aregopts,"keyboard
Layout\preload",HKEY_CURRENT_USER,.t.)
&&获得当前用户可用的汉字输入法
  的个数及其在注册表中所对应的主键
tnumber=alen(aregopts)
public dime aregopts1[tnumber],dime aregopts2
[tnumber],dime aregopts3[tnumber]
for i=1 to tnumber
   frmMyForm.EnumOptions(@aregopts1,"keyboard
Layout\preload\" +aregopts[I],HKEY_CURRENT_USER,.F.)
   &&获得当前用户可用的汉字输入法
    在注册表中所对应的主键值
   aregopts2[i]=aregopts1[2]
   frmMyForm.GetRegKey("layout ;text",@cvalue,
"System\CurrentControlSet\;Control\Keyboard
  layouts\" +aregopts2[i],HKEY_LOCAL_MACHINE)
   &&获得当前用户可用的汉字输入法
  在注册表中所对应的中文名称
   if cvalue=" 美国101" .or. cvalue=" 美国英语"then
      aregopts3[i]=" 英语( 美国)"
   else    
      aregopts3[i]=cvalue
   endif    
endfor
  2. 在Form1 中添加三个标签Label1、Label2、Label3 及编辑框Edit1、Edit2、Memo1,设定其属性

        Label1.Caption= 中文输入编辑框
        Label1.FontSize=12
        Label1.Alignment=1 -右
        Label2.Caption= 西文输入编辑框
        Label2.FontSize=12
        Label2.Alignment=1 -右
        Label3.Caption= 中文多行文本编辑器
        Label3.FontSize=12
        Label3.Alignment=1 -右
        Text1.imemode=0 -无控件(默认)
        Text2.imemode=2 -关闭IME
        Text3.imemode=0 -无控件(默认)
  在Text1、Text3 的属性gotfocus 中写入以下代码:

ActivateKeyboardLayout(handle, 'KLF_ACTIVATE')  
&&激活用户&&选择的输入法
  3. 在Form1 中添加一标签Label4,设定其属性为

        Alignment=1 -右
        Caption = 选择最喜欢的输入法
        Font.Size=12
        ForeColor=255,0,0
        BackColor=192,192,192
    在Form1 中添加一下拉组合框Combo1,
        Combo1.Style="1 -下拉一列表框"
        Combo1.Rowsourcetype=aregopts4
        Combo1.Rowsource=5 -数组
  在属性中选择ckick event, 对此事件编程,写入以下代码:

*此段程序用于将十六进制字符串
   转换为十进制整数
*VFP 本身没有相应的转换函数
private return1,return2,counter,
    length,flag,strings
counter=1
do while counter<=tnumber
   if this.value=aregopts3[counter]
     strings=aregopts2[counter]
     clea
      exit
   endif
   counter=counter +1
enddo
    length=len(strings)
flag=substr(strings,1,1)
IF flag>'8'  
  &&若最高位为大于8 的数字,
则其对应的数字为负数
   temp2=''
   return2=''
   i1=1
   for i1=1 to length
  &&对各位进行取反操作
    TEMP1=substr(stringS,i1,1)
    if temp1>'9'
      TEMP2=chr(5 -(ASC(TEMP1) -65) +48)
      else
       if temp1>'5'
       TEMP2=chr(15 -(ASC(TEMP1) -48) +48)
       else
          temp2=chr(15 -(ASC(TEMP1) -48) +55)
       endif
    endif
    return2=return2 +temp2  
&&return2 为生成的反码
   endfor
   STRINGS=RETURN2
endif    
return1=0
I=1
FOR i=1 to length
&&将十六进制数字符串
       转换为十进制数
   TEMP1=substr(strings,i,1)
   if temp1>'9'
      TEMP2=ASC(TEMP1) -65 +10
   ELSE
      TEMP2=ASC(TEMP1) -48
   ENDIF
   return1=TEMP2 *16^(length -i) +return1
endfor
if flag>'8'
   handle=INT(0 -(return1 +1))
&&若为负数,
   对转换的十进制数加1,取负
ELSE
   handle=INT(Return1)
endif
  4. 在Form1 中添加一命令按钮Button1,设置其属性:

       Caption= 退出
       FontSize=12
  双击此命令按钮,对其Click 事件编程,写入以下程序:

       ThisForm.Release
       Clear dlls
  整个示例程序设计过程完成,将此表单保存为Form1,选择菜单" 表单(M)" 中的" 执行表单(R)" 命令。

  首先,利用下拉组合框选择你所喜欢的汉字输入法,将光标移到中文输入编辑框中,会发现你选择的汉字输入法自动在屏幕上出现,再将光标移到西文输入编辑框中,汉字输入法自动关闭,如果将光标放到中文多行文本编辑器中,已选择的汉字输入法又自动出现,并且输入法可以进行多次选择。如果在中文输入框或中文多行文本编辑器中输入西文内容,只需在中文输入法选择框中选择" 英语(美国)" 即可。