《 用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即可。 (福建 潘晓臻)
to jifeng 用您的办法可以打开输入法,但是好像在vsflexgrid中不好用? 因为vsflexgrid在切换单元格焦点时没有将输入法关闭,只是使其不可用了,不知道是怎样控制的……
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分相赠。
太客器啦,我只是Copy&Paste而已
各位的方法好是好,但是还有一个不足,就是切换单元格时任务栏会闪动,我采用方法如下: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 + "空格"),那么上面的方法又不起作用了,各位能否提出一个两全其美的方法呢?
它的原理是:使用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即可。
(福建 潘晓臻)
您的代码我已经试过,可以实现您所说的功能。可否告知我能否在单元格切换焦点时用程序再将输入法打开?
不知道是send哪一个message,好像不是EM_SETIMESTATUS?
我查了winuser.h和windows.h还是没找到……
哎……也许是我太笨了,可否赐教?
用您的办法可以打开输入法,但是好像在vsflexgrid中不好用?
因为vsflexgrid在切换单元格焦点时没有将输入法关闭,只是使其不可用了,不知道是怎样控制的……
通过您的热心帮助,问题已解决,
以下是我的代码:
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分相赠。
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 + "空格"),那么上面的方法又不起作用了,各位能否提出一个两全其美的方法呢?