我有个笨办法,用TextBox来输入算了

解决方案 »

  1.   

    《 用VB读取和控制Windows的中文输入法 》   在Windows中我们可以用“Ctrl+Shift”键来调入或切换中文输入法,但是这样做每次都是使位于输入法列表顶端的那个输入法首先被调用。通常我们都要连续按好几次“Ctrl+Shift”才能将习惯的输入法调出。我编制了一段小程序,通过它可以把任意一个输入法放在输入法列表的顶端。
      它的原理是:使用LoadKeyboardLayout函数可以改变输入法的顺序,只要在第一个参数中传递目标输入法的KeyboardlayoutName,第二个参数用KLF_REORDER就可以了。
      例如,aa = LoadKeyboardLayout(″00000409″, KLF_REORDER) 使英文变成第一。那怎样获得KeyboardlayoutName呢?因为使用GetKeyboardLayoutname可以返回当前输入法的KeyboardlayoutName,所以我们可以先用GetKeyboardLayoutList 函数来取得所有输入法,再用activateKeyboardlayout()函数设置当前输入法,最后就可以得到它的KeyboardlayoutName了。具体步骤如下:
      打开VB后选择标准的EXE文档,在Form1上添加一个Combobox和一个command控件,输入以下程序。
      ′以下的API函数用于输入法操作 
      Private Declare Function GetKeyboardLayoutList Lib ″user32″ _
      (ByVal nBuff As Long, lpList As Long) As Long
      Private Declare Function ImmGetDescription Lib ″imm32.dll″ _
      Alias ″ImmGetDescriptionA″ (ByVal hkl As Long, _
      ByVal lpsz As String, ByVal uBufLen As Long) As Long
      Private Declare Function ImmIsIME Lib ″imm32.dll″ (ByVal hkl As Long) As Long
      Private Declare Function ActivateKeyboardLayout Lib ″user32″ _
      (ByVal hkl As Long, ByVal flags As Long) As Long
      Private Declare Function GetKeyboardLayout Lib ″user32″ (ByVal dwLayout As Long)As Long
      Private Declare Function GetKeyboardLayoutName Lib ″user32″ Alias _
      ″GetKeyboardLayoutNameA″ (ByVal pwszKLID As String) As Long
      Private Declare Function LoadKeyboardLayout Lib ″user32″ Alias ″LoadKeyboardLayoutA″ _
      (ByVal pwszKLID As String, ByVal flags As Long) As Long
      Const KLF_REORDER = &H8
      Private NoOfKBDLayout As Long, i As Long, j As Long
      Private hKB(24) As Long, BuffLen As Long
      Private Buff As String
      Private RetStr As String
      Private RetCount As Long
      Private kln As String
      Private Sub Command1_Click()
      If Combo1.ListIndex = -1 Then′如果用户尚未选择输入法,显示出错信息
      MsgBox ″请先选择一个输入法″
      Exit Sub
      End If
      ′改变输入法顺序
      kln = String(8, 0)
      ActivateKeyboardLayout hKB(Combo1.ListIndex), 0
      res = GetKeyboardLayoutName(kln)
      res = LoadKeyboardLayout(kln, KLF_REORDER)
      ActivateKeyboardLayout hCurKBDLayout, 0
      End Sub
      Private Sub Form_Load()
      Buff = String(255, 0)
      hCurKBDLayout = GetKeyboardLayout(0) ′取得目前的输入法
      NoOfKBDLayout = GetKeyboardLayoutList(25, hKB(0)) ′取得所有输入法
      ′ReDim layoutlist(NoOfKBDLayout) As String
      For i = 1 To NoOfKBDLayout
      If ImmIsIME(hKB(i - 1)) = 1 Then ′中文输入法
      BuffLen = 255
      RetCount = ImmGetDescription(hKB(i - 1), Buff, BuffLen)
      RetStr = Left(Buff, RetCount)
      Combo1.AddItem RetStr
      Else
      RetStr = ″English (American)″ ′英文输入法
      Combo1.AddItem RetStr
      End If
      Next
      ActivateKeyboardLayout hCurKBDLayout, 0 ′恢复原来的输入法
      End Sub
      运行后,在combobox中选择目标输入法,按下command即可。
    (福建 潘晓臻) 
      

  2.   

    thank jifeng
    您的代码我已经试过,可以实现您所说的功能。可否告知我能否在单元格切换焦点时用程序再将输入法打开?
    不知道是send哪一个message,好像不是EM_SETIMESTATUS?
    我查了winuser.h和windows.h还是没找到……
    哎……也许是我太笨了,可否赐教?
      

  3.   

    to jifeng
    用您的办法可以打开输入法,但是好像在vsflexgrid中不好用?
    因为vsflexgrid在切换单元格焦点时没有将输入法关闭,只是使其不可用了,不知道是怎样控制的……
      

  4.   

    to jifeng:
    通过您的热心帮助,问题已解决,
    以下是我的代码:
    Option Explicit'以下的API函数用于输入法操作
    Private Declare Function ActivateKeyboardLayout Lib "user32" (ByVal hkl As Long, ByVal flags As Long) As Long
    Private Declare Function GetKeyboardLayout Lib "user32" (ByVal dwLayout As Long) As Long
    Private Declare Function ImmIsIME Lib "imm32.dll" (ByVal hkl As Long) As Long
    Dim hCurKBDLayout As LongPrivate Sub vsFlexGrid1_KeyDown(KeyCode As Integer, Shift As Integer)
        vsFlexGrid1.EditCell
    End SubPrivate Sub vsFlexGrid1_RowColChange()
        hCurKBDLayout = GetKeyboardLayout(0)   '取得目前的输入法
        If ImmIsIME(hCurKBDLayout) = 1 Then
            ActivateKeyboardLayout 0, 0
            ActivateKeyboardLayout hCurKBDLayout, 0
        End If
    End Sub多谢相助,解决了困扰我两天的问题。20分不够,加够100分相赠。
      

  5.   

    太客器啦,我只是Copy&Paste而已
      

  6.   

    各位的方法好是好,但是还有一个不足,就是切换单元格时任务栏会闪动,我采用方法如下:Private Declare Function GetKeyboardLayout Lib "user32" (ByVal dwLayout As Long) As Long
    Private Declare Function ImmIsIME Lib "imm32.dll" (ByVal hkl As Long) As Long
    Private Declare Function ImmSimulateHotKey Lib "imm32.dll" (ByVal hwnd As Long, ByVal dw As Long) As Long
    Private Const IME_THOTKEY_IME_NONIME_TOGGLE = &H70Private Sub Grid_ValidateEdit(ByVal Row As Long, ByVal Col As Long, Cancel As Boolean)
       Dim i As Long
       i = GetKeyboardLayout(0)
       i = ImmIsIME(i)
       If i = 1 Then
          ImmSimulateHotKey Me.hwnd, IME_THOTKEY_IME_NONIME_TOGGLE
       End if
    End If上面的方法在VB6+Windows 98中通过,但是在Windows 2000中函数ImmSimulateHotKey好像不起作用,于是我将代码改为:Private Sub Grid_ValidateEdit(ByVal Row As Long, ByVal Col As Long, Cancel As Boolean)
       Dim i As Long
       i = GetKeyboardLayout(0)
       i = ImmIsIME(i)
       If i = 1 Then
          SendKeys "^ ", False
       End if
    End If但是新的问题又来了,如果用户改变了中英文输入法的切换热键(默认为Ctrl + "空格"),那么上面的方法又不起作用了,各位能否提出一个两全其美的方法呢?